summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorhyokeun <hyokeun.jeon@samsung.com>2016-12-27 17:29:09 +0900
committerhyokeun <hyokeun.jeon@samsung.com>2016-12-27 17:29:09 +0900
commit2a84d37c88d606fda46a565bcc80e173b4d0a80a (patch)
tree8b755bb78271e76e13fb7db38b670dbc443479e7
parentbd54c25035217800f3b1d39f6472d599cd602d5a (diff)
downloadqemu-upstream.tar.gz
qemu-upstream.tar.bz2
qemu-upstream.zip
Imported Upstream version 2.6.1upstream/2.6.1upstream
-rw-r--r--.gitignore6
-rw-r--r--.travis.yml19
-rw-r--r--CODING_STYLE8
-rw-r--r--HACKING4
-rw-r--r--MAINTAINERS82
-rw-r--r--Makefile80
-rw-r--r--Makefile.objs45
-rw-r--r--Makefile.target16
-rw-r--r--VERSION2
-rw-r--r--accel.c4
-rw-r--r--aio-posix.c3
-rw-r--r--aio-win32.c2
-rw-r--r--arch_init.c9
-rw-r--r--async.c33
-rw-r--r--audio/audio.c36
-rw-r--r--audio/audio.h6
-rw-r--r--audio/audio_int.h3
-rw-r--r--audio/audio_pt_int.h2
-rw-r--r--audio/coreaudio.c12
-rw-r--r--audio/mixeng.c1
-rw-r--r--audio/mixeng.h3
-rw-r--r--audio/noaudio.c1
-rw-r--r--audio/ossaudio.c1
-rw-r--r--audio/paaudio.c11
-rw-r--r--audio/spiceaudio.c1
-rw-r--r--audio/trace-events17
-rw-r--r--audio/wavaudio.c2
-rw-r--r--backends/hostmem.c55
-rw-r--r--backends/msmouse.c122
-rw-r--r--backends/rng-random.c18
-rw-r--r--block.c770
-rw-r--r--block/Makefile.objs3
-rw-r--r--block/archipelago.c4
-rw-r--r--block/backup.c134
-rw-r--r--block/blkdebug.c44
-rwxr-xr-xblock/blkreplay.c34
-rw-r--r--block/blkverify.c27
-rw-r--r--block/block-backend.c461
-rw-r--r--block/bochs.c65
-rw-r--r--block/cloop.c54
-rw-r--r--block/commit.c218
-rw-r--r--block/crypto.c97
-rw-r--r--block/curl.c12
-rw-r--r--block/dirty-bitmap.c6
-rw-r--r--block/dmg.c69
-rw-r--r--block/gluster.c848
-rw-r--r--block/io.c1614
-rw-r--r--block/iscsi.c397
-rw-r--r--block/linux-aio.c179
-rw-r--r--block/mirror.c428
-rw-r--r--block/nbd-client.c120
-rw-r--r--block/nbd-client.h11
-rw-r--r--block/nbd.c222
-rw-r--r--block/nfs.c39
-rw-r--r--block/null.c20
-rw-r--r--block/parallels.c31
-rw-r--r--block/qapi.c15
-rw-r--r--block/qcow.c107
-rw-r--r--block/qcow2-cache.c20
-rw-r--r--block/qcow2-cluster.c185
-rw-r--r--block/qcow2-refcount.c65
-rw-r--r--block/qcow2-snapshot.c27
-rw-r--r--block/qcow2.c426
-rw-r--r--block/qcow2.h19
-rw-r--r--block/qed-check.c3
-rw-r--r--block/qed-table.c5
-rw-r--r--block/qed.c77
-rw-r--r--block/quorum.c100
-rw-r--r--block/raw-aio.h (renamed from include/block/raw-aio.h)18
-rw-r--r--block/raw-posix.c328
-rw-r--r--block/raw-win32.c31
-rw-r--r--block/raw_bsd.c83
-rw-r--r--block/rbd.c71
-rw-r--r--block/sheepdog.c59
-rw-r--r--block/snapshot.c62
-rw-r--r--block/ssh.c81
-rw-r--r--block/stream.c53
-rw-r--r--block/throttle-groups.c252
-rw-r--r--block/trace-events116
-rw-r--r--block/vdi.c140
-rw-r--r--block/vhdx-endian.c1
-rw-r--r--block/vhdx-log.c13
-rw-r--r--block/vhdx.c92
-rw-r--r--block/vmdk.c458
-rw-r--r--block/vpc.c192
-rw-r--r--block/vvfat.c143
-rw-r--r--block/win32-aio.c2
-rw-r--r--blockdev.c625
-rw-r--r--blockjob.c204
-rw-r--r--bootdevice.c5
-rw-r--r--bsd-user/elfload.c1
-rw-r--r--bsd-user/i386/target_syscall.h2
-rw-r--r--bsd-user/main.c39
-rw-r--r--bsd-user/mmap.c1
-rw-r--r--bsd-user/qemu.h7
-rw-r--r--bsd-user/sparc/target_syscall.h2
-rw-r--r--bsd-user/sparc64/target_syscall.h2
-rw-r--r--bsd-user/syscall.c10
-rw-r--r--bsd-user/x86_64/target_syscall.h2
-rwxr-xr-xconfigure420
-rw-r--r--contrib/ivshmem-client/ivshmem-client.h6
-rw-r--r--contrib/ivshmem-server/ivshmem-server.c2
-rw-r--r--contrib/ivshmem-server/ivshmem-server.h6
-rw-r--r--cpu-exec-common.c11
-rw-r--r--cpu-exec.c570
-rw-r--r--cpus.c101
-rw-r--r--cputlb.c85
-rw-r--r--crypto/Makefile.objs5
-rw-r--r--crypto/afsplit.c1
-rw-r--r--crypto/block-luks.c95
-rw-r--r--crypto/block-luks.h6
-rw-r--r--crypto/block-qcow.h6
-rw-r--r--crypto/block.c17
-rw-r--r--crypto/blockpriv.h10
-rw-r--r--crypto/hash-gcrypt.c109
-rw-r--r--crypto/hash-glib.c97
-rw-r--r--crypto/hash-nettle.c154
-rw-r--r--crypto/hash.c113
-rw-r--r--crypto/ivgenpriv.h6
-rw-r--r--crypto/pbkdf-gcrypt.c2
-rw-r--r--crypto/pbkdf-nettle.c2
-rw-r--r--crypto/random-stub.c (renamed from crypto/random-platform.c)37
-rw-r--r--crypto/tlscreds.c26
-rw-r--r--crypto/tlscredspriv.h7
-rw-r--r--crypto/tlscredsx509.c17
-rw-r--r--crypto/tlssession.c26
-rw-r--r--crypto/trace-events19
-rw-r--r--default-configs/aarch64-softmmu.mak3
-rw-r--r--default-configs/arm-softmmu.mak2
-rw-r--r--default-configs/pci.mak1
-rw-r--r--default-configs/ppc64-softmmu.mak1
-rw-r--r--device_tree.c1
-rw-r--r--disas/alpha.c6
-rw-r--r--disas/arm.c3
-rw-r--r--disas/i386.c2
-rw-r--r--disas/m68k.c4
-rw-r--r--disas/mips.c50
-rw-r--r--disas/ppc.c22
-rw-r--r--disas/sparc.c6
-rw-r--r--dma-helpers.c65
-rw-r--r--docs/atomics.txt38
-rw-r--r--docs/build-system.txt5
-rw-r--r--docs/igd-assign.txt133
-rw-r--r--docs/memory.txt9
-rw-r--r--docs/migration.txt4
-rw-r--r--docs/multi-thread-compression.txt2
-rw-r--r--docs/qapi-code-gen.txt114
-rw-r--r--docs/qmp-events.txt12
-rw-r--r--docs/specs/acpi_cpu_hotplug.txt94
-rw-r--r--docs/specs/acpi_nvdimm.txt132
-rw-r--r--docs/specs/parallels.txt2
-rw-r--r--docs/specs/vhost-user.txt26
-rw-r--r--docs/throttle.txt4
-rw-r--r--docs/tracing.txt32
-rw-r--r--docs/usb-storage.txt12
-rw-r--r--docs/virtio-migration.txt6
-rw-r--r--dump.c4
-rw-r--r--exec.c272
-rw-r--r--fpu/softfloat-specialize.h661
-rw-r--r--fpu/softfloat.c172
-rw-r--r--fsdev/9p-iov-marshal.c20
-rw-r--r--fsdev/9p-iov-marshal.h4
-rw-r--r--fsdev/9p-marshal.c2
-rw-r--r--fsdev/9p-marshal.h4
-rw-r--r--fsdev/file-op-9p.h12
-rw-r--r--fsdev/qemu-fsdev-dummy.c2
-rw-r--r--fsdev/qemu-fsdev-opts.c2
-rw-r--r--fsdev/qemu-fsdev.c2
-rw-r--r--fsdev/qemu-fsdev.h2
-rw-r--r--fsdev/virtfs-proxy-helper.texi2
-rw-r--r--gdbstub.c30
-rw-r--r--hmp-commands-info.hx22
-rw-r--r--hmp-commands.hx9
-rw-r--r--hmp.c225
-rw-r--r--hmp.h2
-rw-r--r--hw/9pfs/9p-handle.c24
-rw-r--r--hw/9pfs/9p-local.c36
-rw-r--r--hw/9pfs/9p-proxy.c26
-rw-r--r--hw/9pfs/9p-proxy.h5
-rw-r--r--hw/9pfs/9p-synth.c219
-rw-r--r--hw/9pfs/9p-synth.h5
-rw-r--r--hw/9pfs/9p-xattr.h5
-rw-r--r--hw/9pfs/9p.c214
-rw-r--r--hw/9pfs/9p.h30
-rw-r--r--hw/9pfs/codir.c13
-rw-r--r--hw/9pfs/cofile.c3
-rw-r--r--hw/9pfs/cofs.c3
-rw-r--r--hw/9pfs/coth.c5
-rw-r--r--hw/9pfs/coth.h11
-rw-r--r--hw/9pfs/coxattr.c3
-rw-r--r--hw/9pfs/trace-events47
-rw-r--r--hw/9pfs/virtio-9p-device.c16
-rw-r--r--hw/9pfs/virtio-9p.h4
-rw-r--r--hw/acpi/Makefile.objs4
-rw-r--r--hw/acpi/acpi_interface.c9
-rw-r--r--hw/acpi/aml-build.c98
-rw-r--r--hw/acpi/bios-linker-loader.c180
-rw-r--r--hw/acpi/core.c16
-rw-r--r--hw/acpi/cpu.c561
-rw-r--r--hw/acpi/cpu_hotplug.c267
-rw-r--r--hw/acpi/cpu_hotplug_acpi_table.c136
-rw-r--r--hw/acpi/ich9.c103
-rw-r--r--hw/acpi/ipmi.c105
-rw-r--r--hw/acpi/memory_hotplug.c12
-rw-r--r--hw/acpi/nvdimm.c442
-rw-r--r--hw/acpi/pcihp.c10
-rw-r--r--hw/acpi/piix4.c93
-rw-r--r--hw/acpi/trace-events32
-rw-r--r--hw/alpha/alpha_sys.h5
-rw-r--r--hw/alpha/pci.c1
-rw-r--r--hw/alpha/trace-events4
-rw-r--r--hw/alpha/typhoon.c2
-rw-r--r--hw/arm/Makefile.objs1
-rw-r--r--hw/arm/armv7m.c11
-rw-r--r--hw/arm/ast2400.c76
-rw-r--r--hw/arm/bcm2835_peripherals.c16
-rw-r--r--hw/arm/boot.c43
-rw-r--r--hw/arm/collie.c1
-rw-r--r--hw/arm/digic.c2
-rw-r--r--hw/arm/fsl-imx25.c11
-rw-r--r--hw/arm/fsl-imx31.c11
-rw-r--r--hw/arm/fsl-imx6.c466
-rw-r--r--hw/arm/highbank.c15
-rw-r--r--hw/arm/integratorcp.c37
-rw-r--r--hw/arm/musicpal.c2
-rw-r--r--hw/arm/nseries.c8
-rw-r--r--hw/arm/palmetto-bmc.c34
-rw-r--r--hw/arm/pxa2xx.c38
-rw-r--r--hw/arm/pxa2xx_gpio.c2
-rw-r--r--hw/arm/pxa2xx_pic.c7
-rw-r--r--hw/arm/realview.c11
-rw-r--r--hw/arm/sabrelite.c127
-rw-r--r--hw/arm/spitz.c35
-rw-r--r--hw/arm/stellaris.c55
-rw-r--r--hw/arm/stm32f205_soc.c2
-rw-r--r--hw/arm/strongarm.c67
-rw-r--r--hw/arm/strongarm.h5
-rw-r--r--hw/arm/tosa.c5
-rw-r--r--hw/arm/trace-events4
-rw-r--r--hw/arm/versatilepb.c24
-rw-r--r--hw/arm/vexpress.c9
-rw-r--r--hw/arm/virt-acpi-build.c110
-rw-r--r--hw/arm/virt.c183
-rw-r--r--hw/arm/xilinx_zynq.c19
-rw-r--r--hw/arm/xlnx-ep108.c18
-rw-r--r--hw/arm/xlnx-zynqmp.c154
-rw-r--r--hw/arm/z2.c6
-rw-r--r--hw/audio/cs4231.c12
-rw-r--r--hw/audio/fmopl.h4
-rw-r--r--hw/audio/gus.c2
-rw-r--r--hw/audio/gusemu.h2
-rw-r--r--hw/audio/gustate.h2
-rw-r--r--hw/audio/intel-hda.c66
-rw-r--r--hw/audio/lm4549.h2
-rw-r--r--hw/audio/milkymist-ac97.c28
-rw-r--r--hw/audio/pcspk.c11
-rw-r--r--hw/audio/pl041.c1
-rw-r--r--hw/audio/pl041.h2
-rw-r--r--hw/audio/trace-events19
-rw-r--r--hw/block/block.c28
-rw-r--r--hw/block/dataplane/virtio-blk.c146
-rw-r--r--hw/block/dataplane/virtio-blk.h2
-rw-r--r--hw/block/fdc.c25
-rw-r--r--hw/block/hd-geometry.c3
-rw-r--r--hw/block/m25p80.c490
-rw-r--r--hw/block/nand.c36
-rw-r--r--hw/block/nvme.c76
-rw-r--r--hw/block/onenand.c41
-rw-r--r--hw/block/pflash_cfi01.c14
-rw-r--r--hw/block/pflash_cfi02.c13
-rw-r--r--hw/block/tc58128.c2
-rw-r--r--hw/block/trace-events17
-rw-r--r--hw/block/virtio-blk.c116
-rw-r--r--hw/block/xen_blkif.h173
-rw-r--r--hw/block/xen_disk.c20
-rw-r--r--hw/bt/hci-csr.c68
-rw-r--r--hw/bt/hci.c10
-rw-r--r--hw/bt/l2cap.c13
-rw-r--r--hw/bt/sdp.c1
-rw-r--r--hw/char/bcm2835_aux.c1
-rw-r--r--hw/char/cadence_uart.c33
-rw-r--r--hw/char/digic-uart.c11
-rw-r--r--hw/char/escc.c38
-rw-r--r--hw/char/etraxfs_ser.c27
-rw-r--r--hw/char/imx_serial.c1
-rw-r--r--hw/char/ipoctal232.c2
-rw-r--r--hw/char/lm32_juart.c17
-rw-r--r--hw/char/lm32_uart.c28
-rw-r--r--hw/char/milkymist-uart.c12
-rw-r--r--hw/char/pl011.c12
-rw-r--r--hw/char/sclpconsole-lm.c14
-rw-r--r--hw/char/sclpconsole.c14
-rw-r--r--hw/char/serial.c67
-rw-r--r--hw/char/stm32f2xx_usart.c16
-rw-r--r--hw/char/trace-events49
-rw-r--r--hw/char/virtio-console.c25
-rw-r--r--hw/char/virtio-serial-bus.c62
-rw-r--r--hw/char/xen_console.c1
-rw-r--r--hw/char/xilinx_uartlite.c10
-rw-r--r--hw/core/Makefile.objs4
-rw-r--r--hw/core/bus.c251
-rw-r--r--hw/core/hotplug.c11
-rw-r--r--hw/core/loader.c6
-rw-r--r--hw/core/machine.c70
-rw-r--r--hw/core/nmi.c19
-rw-r--r--hw/core/ptimer.c83
-rw-r--r--hw/core/qdev-properties-system.c75
-rw-r--r--hw/core/qdev-properties.c42
-rw-r--r--hw/core/qdev.c278
-rw-r--r--hw/core/register.c287
-rw-r--r--hw/core/sysbus.c4
-rw-r--r--hw/core/uboot_image.h6
-rw-r--r--hw/cpu/Makefile.objs1
-rw-r--r--hw/cpu/a9mpcore.c1
-rw-r--r--hw/cpu/core.c88
-rw-r--r--hw/cris/axis_dev88.c4
-rw-r--r--hw/cris/boot.h4
-rw-r--r--hw/display/Makefile.objs2
-rw-r--r--hw/display/ads7846.c5
-rw-r--r--hw/display/bcm2835_fb.c1
-rw-r--r--hw/display/blizzard.c120
-rw-r--r--hw/display/blizzard_template.h146
-rw-r--r--hw/display/cg3.c2
-rw-r--r--hw/display/dpcd.c173
-rw-r--r--hw/display/exynos4210_fimd.c19
-rw-r--r--hw/display/jazz_led.c18
-rw-r--r--hw/display/milkymist-tmu2.c27
-rw-r--r--hw/display/milkymist-vgafb.c18
-rw-r--r--hw/display/omap_lcd_template.h10
-rw-r--r--hw/display/omap_lcdc.c48
-rw-r--r--hw/display/pl110.c1
-rw-r--r--hw/display/qxl.c127
-rw-r--r--hw/display/qxl.h9
-rw-r--r--hw/display/ssd0323.c5
-rw-r--r--hw/display/tc6393xb.c1
-rw-r--r--hw/display/trace-events122
-rw-r--r--hw/display/vga.c4
-rw-r--r--hw/display/vga.h6
-rw-r--r--hw/display/vga_int.h5
-rw-r--r--hw/display/virtio-gpu-3d.c14
-rw-r--r--hw/display/virtio-gpu-pci.c4
-rw-r--r--hw/display/virtio-gpu.c251
-rw-r--r--hw/display/virtio-vga.c24
-rw-r--r--hw/display/xenfb.c5
-rw-r--r--hw/display/xlnx_dp.c1338
-rw-r--r--hw/dma/Makefile.objs2
-rw-r--r--hw/dma/bcm2835_dma.c1
-rw-r--r--hw/dma/pl080.c1
-rw-r--r--hw/dma/pl330.c1
-rw-r--r--hw/dma/pxa2xx_dma.c38
-rw-r--r--hw/dma/rc4030.c1
-rw-r--r--hw/dma/trace-events32
-rw-r--r--hw/dma/xlnx-zynq-devcfg.c400
-rw-r--r--hw/dma/xlnx_dpdma.c786
-rw-r--r--hw/gpio/gpio_key.c1
-rw-r--r--hw/gpio/imx_gpio.c1
-rw-r--r--hw/gpio/omap_gpio.c61
-rw-r--r--hw/gpio/pl061.c25
-rw-r--r--hw/gpio/zaurus.c14
-rw-r--r--hw/i2c/Makefile.objs2
-rw-r--r--hw/i2c/aspeed_i2c.c440
-rw-r--r--hw/i2c/bitbang_i2c.c14
-rw-r--r--hw/i2c/core.c165
-rw-r--r--hw/i2c/exynos4210_i2c.c13
-rw-r--r--hw/i2c/i2c-ddc.c308
-rw-r--r--hw/i2c/imx_i2c.c1
-rw-r--r--hw/i2c/omap_i2c.c42
-rw-r--r--hw/i2c/smbus_ich9.c1
-rw-r--r--hw/i2c/versatile_i2c.c20
-rw-r--r--hw/i386/Makefile.objs2
-rw-r--r--hw/i386/acpi-build.c559
-rw-r--r--hw/i386/intel_iommu.c461
-rw-r--r--hw/i386/intel_iommu_internal.h50
-rw-r--r--hw/i386/kvm/apic.c11
-rw-r--r--hw/i386/kvm/clock.c1
-rw-r--r--hw/i386/kvm/i8254.c2
-rw-r--r--hw/i386/kvm/pci-assign.c29
-rw-r--r--hw/i386/kvmvapic.c8
-rw-r--r--hw/i386/pc.c458
-rw-r--r--hw/i386/pc_piix.c126
-rw-r--r--hw/i386/pc_q35.c50
-rw-r--r--hw/i386/trace-events15
-rw-r--r--hw/i386/x86-iommu.c128
-rw-r--r--hw/ide/ahci.c20
-rw-r--r--hw/ide/ahci.h (renamed from include/hw/ide/ahci.h)2
-rw-r--r--hw/ide/atapi.c19
-rw-r--r--hw/ide/cmd646.c10
-rw-r--r--hw/ide/core.c68
-rw-r--r--hw/ide/ich.c21
-rw-r--r--hw/ide/internal.h (renamed from include/hw/ide/internal.h)10
-rw-r--r--hw/ide/isa.c8
-rw-r--r--hw/ide/macio.c66
-rw-r--r--hw/ide/microdrive.c8
-rw-r--r--hw/ide/mmio.c2
-rw-r--r--hw/ide/pci.c10
-rw-r--r--hw/ide/pci.h (renamed from include/hw/ide/pci.h)2
-rw-r--r--hw/ide/piix.c10
-rw-r--r--hw/ide/qdev.c10
-rw-r--r--hw/ide/via.c10
-rw-r--r--hw/input/hid.c3
-rw-r--r--hw/input/pckbd.c21
-rw-r--r--hw/input/pl050.c1
-rw-r--r--hw/input/trace-events31
-rw-r--r--hw/input/virtio-input.c40
-rw-r--r--hw/intc/Makefile.objs6
-rw-r--r--hw/intc/allwinner-a10-pic.c1
-rw-r--r--hw/intc/apic.c28
-rw-r--r--hw/intc/apic_common.c35
-rw-r--r--hw/intc/arm_gic.c81
-rw-r--r--hw/intc/arm_gic_kvm.c2
-rw-r--r--hw/intc/arm_gicv2m.c2
-rw-r--r--hw/intc/arm_gicv3.c400
-rw-r--r--hw/intc/arm_gicv3_common.c225
-rw-r--r--hw/intc/arm_gicv3_cpuif.c1348
-rw-r--r--hw/intc/arm_gicv3_dist.c880
-rw-r--r--hw/intc/arm_gicv3_kvm.c8
-rw-r--r--hw/intc/arm_gicv3_redist.c567
-rw-r--r--hw/intc/armv7m_nvic.c10
-rw-r--r--hw/intc/aspeed_vic.c2
-rw-r--r--hw/intc/bcm2835_ic.c1
-rw-r--r--hw/intc/bcm2836_control.c1
-rw-r--r--hw/intc/etraxfs_pic.c13
-rw-r--r--hw/intc/exynos4210_combiner.c14
-rw-r--r--hw/intc/exynos4210_gic.c39
-rw-r--r--hw/intc/gic_internal.h2
-rw-r--r--hw/intc/gicv3_internal.h331
-rw-r--r--hw/intc/grlib_irqmp.c27
-rw-r--r--hw/intc/i8259.c1
-rw-r--r--hw/intc/imx_avic.c16
-rw-r--r--hw/intc/ioapic.c203
-rw-r--r--hw/intc/lm32_pic.c12
-rw-r--r--hw/intc/mips_gic.c460
-rw-r--r--hw/intc/omap_intc.c64
-rw-r--r--hw/intc/openpic.c1
-rw-r--r--hw/intc/openpic_kvm.c2
-rw-r--r--hw/intc/pl190.c14
-rw-r--r--hw/intc/s390_flic.c8
-rw-r--r--hw/intc/s390_flic_kvm.c33
-rw-r--r--hw/intc/slavio_intctl.c14
-rw-r--r--hw/intc/trace-events123
-rw-r--r--hw/intc/xics.c556
-rw-r--r--hw/intc/xics_kvm.c72
-rw-r--r--hw/intc/xics_spapr.c434
-rw-r--r--hw/ipack/ipack.c2
-rw-r--r--hw/ipack/tpci200.c2
-rw-r--r--hw/ipmi/ipmi.c34
-rw-r--r--hw/ipmi/ipmi_bmc_extern.c2
-rw-r--r--hw/ipmi/isa_ipmi_bt.c57
-rw-r--r--hw/ipmi/isa_ipmi_kcs.c56
-rw-r--r--hw/isa/isa-bus.c7
-rw-r--r--hw/isa/lpc_ich9.c129
-rw-r--r--hw/isa/trace-events9
-rw-r--r--hw/lm32/lm32.h21
-rw-r--r--hw/lm32/lm32_boards.c9
-rw-r--r--hw/lm32/milkymist-hw.h14
-rw-r--r--hw/lm32/milkymist.c8
-rw-r--r--hw/mem/nvdimm.c133
-rw-r--r--hw/mem/pc-dimm.c40
-rw-r--r--hw/microblaze/boot.h6
-rw-r--r--hw/microblaze/petalogix_ml605_mmu.c9
-rw-r--r--hw/microblaze/petalogix_s3adsp1800_mmu.c5
-rw-r--r--hw/mips/cps.c34
-rw-r--r--hw/mips/cputimer.c4
-rw-r--r--hw/mips/gt64xxx_pci.c2
-rw-r--r--hw/mips/mips_fulong2e.c4
-rw-r--r--hw/mips/mips_int.c3
-rw-r--r--hw/mips/mips_jazz.c4
-rw-r--r--hw/mips/mips_malta.c11
-rw-r--r--hw/mips/mips_mipssim.c4
-rw-r--r--hw/mips/mips_r4k.c4
-rw-r--r--hw/misc/Makefile.objs3
-rw-r--r--hw/misc/arm11scu.c1
-rw-r--r--hw/misc/arm_integrator_debug.c1
-rw-r--r--hw/misc/arm_l2x0.c12
-rw-r--r--hw/misc/arm_sysctl.c1
-rw-r--r--hw/misc/aspeed_scu.c282
-rw-r--r--hw/misc/auxbus.c292
-rw-r--r--hw/misc/bcm2835_mbox.c1
-rw-r--r--hw/misc/bcm2835_property.c34
-rw-r--r--hw/misc/exynos4210_pmu.c11
-rw-r--r--hw/misc/hyperv_testdev.c2
-rw-r--r--hw/misc/imx25_ccm.c1
-rw-r--r--hw/misc/imx31_ccm.c1
-rw-r--r--hw/misc/imx6_ccm.c7
-rw-r--r--hw/misc/imx6_src.c265
-rw-r--r--hw/misc/imx_ccm.c1
-rw-r--r--hw/misc/ivshmem.c25
-rw-r--r--hw/misc/macio/cuda.c1
-rw-r--r--hw/misc/macio/mac_dbdma.c135
-rw-r--r--hw/misc/max111x.c12
-rw-r--r--hw/misc/milkymist-hpdmc.c2
-rw-r--r--hw/misc/milkymist-pfpu.c2
-rw-r--r--hw/misc/mips_cmgcr.c88
-rw-r--r--hw/misc/mips_cpc.c7
-rw-r--r--hw/misc/mips_itu.c3
-rw-r--r--hw/misc/mst_fpga.c13
-rw-r--r--hw/misc/pc-testdev.c3
-rw-r--r--hw/misc/pci-testdev.c1
-rw-r--r--hw/misc/stm32f2xx_syscfg.c1
-rw-r--r--hw/misc/trace-events55
-rw-r--r--hw/misc/vmport.c1
-rw-r--r--hw/misc/zynq-xadc.c1
-rw-r--r--hw/misc/zynq_slcr.c1
-rw-r--r--hw/net/Makefile.objs6
-rw-r--r--hw/net/allwinner_emac.c3
-rw-r--r--hw/net/cadence_gem.c15
-rw-r--r--hw/net/dp8393x.c2
-rw-r--r--hw/net/e1000.c437
-rw-r--r--hw/net/e1000_regs.h356
-rw-r--r--hw/net/e1000e.c711
-rw-r--r--hw/net/e1000e_core.c3483
-rw-r--r--hw/net/e1000e_core.h146
-rw-r--r--hw/net/e1000x_common.c267
-rw-r--r--hw/net/e1000x_common.h213
-rw-r--r--hw/net/eepro100.c10
-rw-r--r--hw/net/etraxfs_eth.c2
-rw-r--r--hw/net/fsl_etsec/etsec.c3
-rw-r--r--hw/net/fsl_etsec/etsec.h7
-rw-r--r--hw/net/fsl_etsec/registers.h6
-rw-r--r--hw/net/fsl_etsec/rings.c2
-rw-r--r--hw/net/imx_fec.c1010
-rw-r--r--hw/net/lan9118.c3
-rw-r--r--hw/net/lance.c2
-rw-r--r--hw/net/mcf_fec.c2
-rw-r--r--hw/net/milkymist-minimac2.c2
-rw-r--r--hw/net/mipsnet.c10
-rw-r--r--hw/net/ne2000-isa.c6
-rw-r--r--hw/net/ne2000.c2
-rw-r--r--hw/net/ne2000.h2
-rw-r--r--hw/net/net_rx_pkt.c600
-rw-r--r--hw/net/net_rx_pkt.h363
-rw-r--r--hw/net/net_tx_pkt.h190
-rw-r--r--hw/net/opencores_eth.c46
-rw-r--r--hw/net/pcnet-pci.c2
-rw-r--r--hw/net/pcnet.h2
-rw-r--r--hw/net/rocker/rocker.h6
-rw-r--r--hw/net/rocker/rocker_desc.h5
-rw-r--r--hw/net/rocker/rocker_fp.c2
-rw-r--r--hw/net/rocker/rocker_fp.h6
-rw-r--r--hw/net/rocker/rocker_hw.h6
-rw-r--r--hw/net/rocker/rocker_of_dpa.c5
-rw-r--r--hw/net/rocker/rocker_of_dpa.h6
-rw-r--r--hw/net/rocker/rocker_tlv.h10
-rw-r--r--hw/net/rocker/rocker_world.h6
-rw-r--r--hw/net/rtl8139.c56
-rw-r--r--hw/net/smc91c111.c2
-rw-r--r--hw/net/spapr_llan.c56
-rw-r--r--hw/net/stellaris_enet.c2
-rw-r--r--hw/net/trace-events272
-rw-r--r--hw/net/vhost_net.c85
-rw-r--r--hw/net/virtio-net.c114
-rw-r--r--hw/net/vmware_utils.h55
-rw-r--r--hw/net/vmxnet3.c395
-rw-r--r--hw/net/vmxnet3.h4
-rw-r--r--hw/net/vmxnet_debug.h9
-rw-r--r--hw/net/vmxnet_rx_pkt.c187
-rw-r--r--hw/net/vmxnet_rx_pkt.h174
-rw-r--r--hw/net/vmxnet_tx_pkt.c (renamed from hw/net/net_tx_pkt.c)362
-rw-r--r--hw/net/vmxnet_tx_pkt.h146
-rw-r--r--hw/net/xen_nic.c3
-rw-r--r--hw/net/xgmac.c2
-rw-r--r--hw/net/xilinx_axienet.c2
-rw-r--r--hw/net/xilinx_ethlite.c6
-rw-r--r--hw/nvram/fw_cfg.c28
-rw-r--r--hw/nvram/spapr_nvram.c25
-rw-r--r--hw/nvram/trace-events10
-rw-r--r--hw/pci-bridge/dec.h4
-rw-r--r--hw/pci-bridge/ioh3420.c23
-rw-r--r--hw/pci-bridge/pci_bridge_dev.c35
-rw-r--r--hw/pci-bridge/pci_expander_bridge.c56
-rw-r--r--hw/pci-bridge/xio3130_downstream.c21
-rw-r--r--hw/pci-bridge/xio3130_upstream.c19
-rw-r--r--hw/pci-bridge/xio3130_upstream.h2
-rw-r--r--hw/pci-host/apb.c21
-rw-r--r--hw/pci-host/grackle.c2
-rw-r--r--hw/pci-host/piix.c32
-rw-r--r--hw/pci-host/prep.c1
-rw-r--r--hw/pci-host/q35.c92
-rw-r--r--hw/pci-host/uninorth.c5
-rw-r--r--hw/pci-host/versatile.c2
-rw-r--r--hw/pci/msi.c27
-rw-r--r--hw/pci/msix.c2
-rw-r--r--hw/pci/pci.c171
-rw-r--r--hw/pci/pcie.c95
-rw-r--r--hw/pci/pcie_aer.c1
-rw-r--r--hw/pci/trace-events9
-rw-r--r--hw/ppc/Makefile.objs2
-rw-r--r--hw/ppc/e500.c2
-rw-r--r--hw/ppc/e500.h2
-rw-r--r--hw/ppc/e500plat.c1
-rw-r--r--hw/ppc/mac.h7
-rw-r--r--hw/ppc/mac_newworld.c1
-rw-r--r--hw/ppc/mac_oldworld.c2
-rw-r--r--hw/ppc/ppc.c65
-rw-r--r--hw/ppc/ppc405.h6
-rw-r--r--hw/ppc/ppc4xx_devs.c1
-rw-r--r--hw/ppc/ppce500_spin.c9
-rw-r--r--hw/ppc/prep.c3
-rw-r--r--hw/ppc/spapr.c373
-rw-r--r--hw/ppc/spapr_cpu_core.c432
-rw-r--r--hw/ppc/spapr_drc.c25
-rw-r--r--hw/ppc/spapr_events.c11
-rw-r--r--hw/ppc/spapr_hcall.c90
-rw-r--r--hw/ppc/spapr_iommu.c211
-rw-r--r--hw/ppc/spapr_pci.c123
-rw-r--r--hw/ppc/spapr_pci_vfio.c7
-rw-r--r--hw/ppc/spapr_rtas.c26
-rw-r--r--hw/ppc/spapr_rtas_ddw.c295
-rw-r--r--hw/ppc/spapr_vio.c18
-rw-r--r--hw/ppc/trace-events43
-rw-r--r--hw/ppc/virtex_ml507.c1
-rw-r--r--hw/s390x/Makefile.objs2
-rw-r--r--hw/s390x/ccw-device.c27
-rw-r--r--hw/s390x/ccw-device.h43
-rw-r--r--hw/s390x/css-bridge.c148
-rw-r--r--hw/s390x/css.c278
-rw-r--r--hw/s390x/css.h (renamed from include/hw/s390x/css.h)66
-rw-r--r--hw/s390x/ipl.c91
-rw-r--r--hw/s390x/ipl.h97
-rw-r--r--hw/s390x/s390-pci-bus.c608
-rw-r--r--hw/s390x/s390-pci-bus.h98
-rw-r--r--hw/s390x/s390-pci-inst.c349
-rw-r--r--hw/s390x/s390-pci-inst.h20
-rw-r--r--hw/s390x/s390-skeys.c27
-rw-r--r--hw/s390x/s390-virtio-ccw.c65
-rw-r--r--hw/s390x/s390-virtio.h2
-rw-r--r--hw/s390x/sclp.c4
-rw-r--r--hw/s390x/sclpquiesce.c2
-rw-r--r--hw/s390x/trace-events15
-rw-r--r--hw/s390x/virtio-ccw.c457
-rw-r--r--hw/s390x/virtio-ccw.h39
-rw-r--r--hw/scsi/esp.c5
-rw-r--r--hw/scsi/megasas.c70
-rw-r--r--hw/scsi/mfi.h6
-rw-r--r--hw/scsi/mptsas.c38
-rw-r--r--hw/scsi/mptsas.h3
-rw-r--r--hw/scsi/scsi-bus.c41
-rw-r--r--hw/scsi/scsi-disk.c468
-rw-r--r--hw/scsi/scsi-generic.c21
-rw-r--r--hw/scsi/trace-events204
-rw-r--r--hw/scsi/vhost-scsi.c6
-rw-r--r--hw/scsi/virtio-scsi-dataplane.c15
-rw-r--r--hw/scsi/virtio-scsi.c110
-rw-r--r--hw/scsi/vmw_pvscsi.c17
-rw-r--r--hw/sd/milkymist-memcard.c2
-rw-r--r--hw/sd/pl181.c27
-rw-r--r--hw/sd/sd.c52
-rw-r--r--hw/sd/sdhci.c1
-rw-r--r--hw/sd/ssi-sd.c9
-rw-r--r--hw/sd/trace-events5
-rw-r--r--hw/sh4/sh7750.c1
-rw-r--r--hw/sh4/sh7750_regnames.h6
-rw-r--r--hw/sh4/sh7750_regs.h4
-rw-r--r--hw/sh4/sh_pci.c4
-rw-r--r--hw/smbios/Makefile.objs1
-rw-r--r--hw/smbios/smbios.c72
-rw-r--r--hw/smbios/smbios_build.h87
-rw-r--r--hw/smbios/smbios_type_38.c117
-rw-r--r--hw/sparc/leon3.c6
-rw-r--r--hw/sparc/sun4m.c2
-rw-r--r--hw/sparc/trace-events11
-rw-r--r--hw/ssi/Makefile.objs2
-rw-r--r--hw/ssi/aspeed_smc.c469
-rw-r--r--hw/ssi/imx_spi.c455
-rw-r--r--hw/ssi/pl022.c1
-rw-r--r--hw/ssi/ssi.c6
-rw-r--r--hw/timer/Makefile.objs1
-rw-r--r--hw/timer/allwinner-a10-pit.c1
-rw-r--r--hw/timer/arm_timer.c1
-rw-r--r--hw/timer/aspeed_timer.c139
-rw-r--r--hw/timer/digic-timer.c1
-rw-r--r--hw/timer/imx_epit.c1
-rw-r--r--hw/timer/imx_gpt.c70
-rw-r--r--hw/timer/lm32_timer.c19
-rw-r--r--hw/timer/mc146818rtc.c11
-rw-r--r--hw/timer/milkymist-sysctl.c23
-rw-r--r--hw/timer/mips_gictimer.c142
-rw-r--r--hw/timer/omap_gptimer.c4
-rw-r--r--hw/timer/pl031.c1
-rw-r--r--hw/timer/stm32f2xx_timer.c1
-rw-r--r--hw/timer/trace-events51
-rw-r--r--hw/tpm/tpm_util.h7
-rw-r--r--hw/usb/Makefile.objs4
-rw-r--r--hw/usb/bus.c58
-rw-r--r--hw/usb/desc.c1
-rw-r--r--hw/usb/dev-mtp.c4
-rw-r--r--hw/usb/dev-network.c67
-rw-r--r--hw/usb/dev-storage.c52
-rw-r--r--hw/usb/dev-uas.c5
-rw-r--r--hw/usb/hcd-ehci.c31
-rw-r--r--hw/usb/hcd-ehci.h5
-rw-r--r--hw/usb/hcd-ohci.c2
-rw-r--r--hw/usb/hcd-xhci.c42
-rw-r--r--hw/usb/host-libusb.c79
-rw-r--r--hw/usb/redirect.c12
-rw-r--r--hw/usb/trace-events268
-rw-r--r--hw/usb/xen-usb.c1107
-rw-r--r--hw/vfio/Makefile.objs1
-rw-r--r--hw/vfio/common.c328
-rw-r--r--hw/vfio/pci-quirks.c643
-rw-r--r--hw/vfio/pci.c273
-rw-r--r--hw/vfio/pci.h8
-rw-r--r--hw/vfio/platform.c2
-rw-r--r--hw/vfio/spapr.c209
-rw-r--r--hw/vfio/trace-events125
-rw-r--r--hw/virtio/trace-events16
-rw-r--r--hw/virtio/vhost-backend.c13
-rw-r--r--hw/virtio/vhost-user.c124
-rw-r--r--hw/virtio/vhost.c213
-rw-r--r--hw/virtio/virtio-balloon.c38
-rw-r--r--hw/virtio/virtio-bus.c126
-rw-r--r--hw/virtio/virtio-mmio.c177
-rw-r--r--hw/virtio/virtio-pci.c172
-rw-r--r--hw/virtio/virtio-pci.h21
-rw-r--r--hw/virtio/virtio-rng.c20
-rw-r--r--hw/virtio/virtio.c79
-rw-r--r--hw/watchdog/watchdog.c2
-rw-r--r--hw/watchdog/wdt_diag288.c1
-rw-r--r--hw/xen/xen-host-pci-device.h2
-rw-r--r--hw/xen/xen_backend.c173
-rw-r--r--hw/xen/xen_devconfig.c52
-rw-r--r--hw/xen/xen_pt.h2
-rw-r--r--hw/xen/xen_pt_config_init.c5
-rw-r--r--hw/xen/xen_pt_msi.c1
-rw-r--r--hw/xenpv/xen_domainbuild.h2
-rw-r--r--hw/xenpv/xen_machine_pv.c4
-rw-r--r--hw/xtensa/bootparam.h4
-rw-r--r--hw/xtensa/pic_cpu.c5
-rw-r--r--hw/xtensa/xtfpga.c2
-rw-r--r--include/block/aio.h17
-rw-r--r--include/block/block.h138
-rw-r--r--include/block/block_int.h259
-rw-r--r--include/block/blockjob.h106
-rw-r--r--include/block/dirty-bitmap.h4
-rw-r--r--include/block/nbd.h22
-rw-r--r--include/block/scsi.h11
-rw-r--r--include/block/thread-pool.h2
-rw-r--r--include/block/throttle-groups.h13
-rw-r--r--include/crypto/aes.h5
-rw-r--r--include/crypto/afsplit.h6
-rw-r--r--include/crypto/block.h22
-rw-r--r--include/crypto/cipher.h6
-rw-r--r--include/crypto/desrfb.h5
-rw-r--r--include/crypto/hash.h6
-rw-r--r--include/crypto/init.h6
-rw-r--r--include/crypto/ivgen.h6
-rw-r--r--include/crypto/pbkdf.h6
-rw-r--r--include/crypto/random.h6
-rw-r--r--include/crypto/secret.h6
-rw-r--r--include/crypto/tlscreds.h8
-rw-r--r--include/crypto/tlscredsanon.h7
-rw-r--r--include/crypto/tlscredsx509.h7
-rw-r--r--include/crypto/tlssession.h6
-rw-r--r--include/crypto/xts.h7
-rw-r--r--include/disas/bfd.h11
-rw-r--r--include/disas/disas.h8
-rw-r--r--include/elf.h22
-rw-r--r--include/exec/address-spaces.h4
-rw-r--r--include/exec/cpu-all.h48
-rw-r--r--include/exec/cpu-common.h32
-rw-r--r--include/exec/cpu-defs.h1
-rw-r--r--include/exec/cpu_ldst_template.h25
-rw-r--r--include/exec/cpu_ldst_useronly_template.h22
-rw-r--r--include/exec/exec-all.h186
-rw-r--r--include/exec/gdbstub.h3
-rw-r--r--include/exec/gen-icount.h20
-rw-r--r--include/exec/helper-gen.h4
-rw-r--r--include/exec/helper-head.h30
-rw-r--r--include/exec/helper-proto.h4
-rw-r--r--include/exec/helper-tcg.h4
-rw-r--r--include/exec/hwaddr.h1
-rw-r--r--include/exec/ioport.h19
-rw-r--r--include/exec/memory.h105
-rw-r--r--include/exec/poison.h8
-rw-r--r--include/exec/ram_addr.h5
-rw-r--r--include/exec/softmmu-semi.h3
-rw-r--r--include/exec/tb-context.h45
-rw-r--r--include/exec/tb-hash-xx.h95
-rw-r--r--include/exec/tb-hash.h11
-rw-r--r--include/exec/user/abitypes.h9
-rw-r--r--include/exec/user/thunk.h15
-rw-r--r--include/fpu/softfloat.h51
-rw-r--r--include/glib-compat.h46
-rw-r--r--include/hw/acpi/acpi-defs.h34
-rw-r--r--include/hw/acpi/acpi.h20
-rw-r--r--include/hw/acpi/acpi_dev_interface.h18
-rw-r--r--include/hw/acpi/aml-build.h27
-rw-r--r--include/hw/acpi/bios-linker-loader.h29
-rw-r--r--include/hw/acpi/cpu.h67
-rw-r--r--include/hw/acpi/cpu_hotplug.h28
-rw-r--r--include/hw/acpi/ich9.h12
-rw-r--r--include/hw/acpi/ipmi.h22
-rw-r--r--include/hw/acpi/memory_hotplug.h4
-rw-r--r--include/hw/acpi/pcihp.h5
-rw-r--r--include/hw/arm/arm.h8
-rw-r--r--include/hw/arm/ast2400.h7
-rw-r--r--include/hw/arm/digic.h1
-rw-r--r--include/hw/arm/exynos4210.h8
-rw-r--r--include/hw/arm/fsl-imx6.h453
-rw-r--r--include/hw/arm/omap.h1
-rw-r--r--include/hw/arm/pxa.h6
-rw-r--r--include/hw/arm/soc_dma.h3
-rw-r--r--include/hw/arm/stm32f205_soc.h4
-rw-r--r--include/hw/arm/virt-acpi-build.h1
-rw-r--r--include/hw/arm/virt.h5
-rw-r--r--include/hw/arm/xlnx-zynqmp.h9
-rw-r--r--include/hw/audio/audio.h4
-rw-r--r--include/hw/audio/pcspk.h4
-rw-r--r--include/hw/block/block.h17
-rw-r--r--include/hw/block/flash.h5
-rw-r--r--include/hw/boards.h18
-rw-r--r--include/hw/bt.h2
-rw-r--r--include/hw/char/cadence_uart.h17
-rw-r--r--include/hw/char/escc.h2
-rw-r--r--include/hw/char/lm32_juart.h2
-rw-r--r--include/hw/char/pl011.h52
-rw-r--r--include/hw/char/serial.h6
-rw-r--r--include/hw/char/xilinx_uartlite.h35
-rw-r--r--include/hw/compat.h15
-rw-r--r--include/hw/cpu/core.h34
-rw-r--r--include/hw/cris/etraxfs.h20
-rw-r--r--include/hw/cris/etraxfs_dma.h2
-rw-r--r--include/hw/display/dpcd.h105
-rw-r--r--include/hw/display/xlnx_dp.h109
-rw-r--r--include/hw/dma/xlnx_dpdma.h85
-rw-r--r--include/hw/empty_slot.h2
-rw-r--r--include/hw/fw-path-provider.h2
-rw-r--r--include/hw/gpio/imx_gpio.h8
-rw-r--r--include/hw/hotplug.h14
-rw-r--r--include/hw/hw.h60
-rw-r--r--include/hw/i2c/aspeed_i2c.h62
-rw-r--r--include/hw/i2c/i2c-ddc.h38
-rw-r--r--include/hw/i2c/i2c.h1
-rw-r--r--include/hw/i2c/imx_i2c.h8
-rw-r--r--include/hw/i2c/pm_smbus.h2
-rw-r--r--include/hw/i386/apic-msidef.h1
-rw-r--r--include/hw/i386/apic.h5
-rw-r--r--include/hw/i386/apic_internal.h8
-rw-r--r--include/hw/i386/ich9.h12
-rw-r--r--include/hw/i386/intel_iommu.h170
-rw-r--r--include/hw/i386/ioapic.h2
-rw-r--r--include/hw/i386/ioapic_internal.h14
-rw-r--r--include/hw/i386/pc.h90
-rw-r--r--include/hw/i386/topology.h15
-rw-r--r--include/hw/i386/x86-iommu.h100
-rw-r--r--include/hw/input/adb.h6
-rw-r--r--include/hw/input/ps2.h2
-rw-r--r--include/hw/intc/allwinner-a10-pic.h4
-rw-r--r--include/hw/intc/arm_gic.h3
-rw-r--r--include/hw/intc/arm_gicv3.h32
-rw-r--r--include/hw/intc/arm_gicv3_common.h218
-rw-r--r--include/hw/intc/mips_gic.h216
-rw-r--r--include/hw/ipack/ipack.h2
-rw-r--r--include/hw/ipmi/ipmi.h74
-rw-r--r--include/hw/isa/i8257.h1
-rw-r--r--include/hw/isa/i8259_internal.h2
-rw-r--r--include/hw/isa/isa.h3
-rw-r--r--include/hw/m68k/mcf.h2
-rw-r--r--include/hw/mem/nvdimm.h58
-rw-r--r--include/hw/mem/pc-dimm.h13
-rw-r--r--include/hw/mips/cps.h2
-rw-r--r--include/hw/mips/cpudevs.h7
-rw-r--r--include/hw/misc/arm_integrator_debug.h5
-rw-r--r--include/hw/misc/aspeed_scu.h39
-rw-r--r--include/hw/misc/auxbus.h128
-rw-r--r--include/hw/misc/imx6_src.h73
-rw-r--r--include/hw/misc/imx_ccm.h5
-rw-r--r--include/hw/misc/mips_cmgcr.h33
-rw-r--r--include/hw/misc/tmp105_regs.h5
-rw-r--r--include/hw/net/allwinner_emac.h5
-rw-r--r--include/hw/net/imx_fec.h250
-rw-r--r--include/hw/nmi.h3
-rw-r--r--include/hw/nvram/fw_cfg.h1
-rw-r--r--include/hw/nvram/openbios_firmware_abi.h6
-rw-r--r--include/hw/pci-host/apb.h4
-rw-r--r--include/hw/pci-host/ppce500.h4
-rw-r--r--include/hw/pci-host/q35.h20
-rw-r--r--include/hw/pci-host/spapr.h22
-rw-r--r--include/hw/pci/msi.h3
-rw-r--r--include/hw/pci/msix.h1
-rw-r--r--include/hw/pci/pci.h39
-rw-r--r--include/hw/pci/pci_bridge.h2
-rw-r--r--include/hw/pci/pci_bus.h2
-rw-r--r--include/hw/pci/pci_ids.h3
-rw-r--r--include/hw/pci/pci_regs.h2
-rw-r--r--include/hw/pci/pcie.h5
-rw-r--r--include/hw/pci/pcie_regs.h5
-rw-r--r--include/hw/pcmcia.h2
-rw-r--r--include/hw/platform-bus.h4
-rw-r--r--include/hw/ppc/mac_dbdma.h8
-rw-r--r--include/hw/ppc/openpic.h9
-rw-r--r--include/hw/ppc/ppc.h27
-rw-r--r--include/hw/ppc/ppc4xx.h6
-rw-r--r--include/hw/ppc/spapr.h50
-rw-r--r--include/hw/ppc/spapr_cpu_core.h36
-rw-r--r--include/hw/ppc/spapr_drc.h10
-rw-r--r--include/hw/ppc/spapr_vio.h11
-rw-r--r--include/hw/ppc/xics.h63
-rw-r--r--include/hw/ptimer.h1
-rw-r--r--include/hw/qdev-core.h7
-rw-r--r--include/hw/qdev-properties.h14
-rw-r--r--include/hw/register.h255
-rw-r--r--include/hw/s390x/css-bridge.h38
-rw-r--r--include/hw/s390x/ebcdic.h6
-rw-r--r--include/hw/s390x/event-facility.h2
-rw-r--r--include/hw/s390x/s390-virtio-ccw.h4
-rw-r--r--include/hw/s390x/s390_flic.h8
-rw-r--r--include/hw/s390x/sclp.h5
-rw-r--r--include/hw/s390x/storage-keys.h8
-rw-r--r--include/hw/scsi/scsi.h7
-rw-r--r--include/hw/sd/sd.h9
-rw-r--r--include/hw/sh4/sh.h1
-rw-r--r--include/hw/sh4/sh_intc.h6
-rw-r--r--include/hw/smbios/ipmi.h15
-rw-r--r--include/hw/smbios/smbios.h5
-rw-r--r--include/hw/sparc/grlib.h6
-rw-r--r--include/hw/ssi/aspeed_smc.h100
-rw-r--r--include/hw/ssi/imx_spi.h103
-rw-r--r--include/hw/ssi/ssi.h2
-rw-r--r--include/hw/ssi/xilinx_spips.h6
-rw-r--r--include/hw/stream.h2
-rw-r--r--include/hw/sysbus.h8
-rw-r--r--include/hw/timer/a9gtimer.h6
-rw-r--r--include/hw/timer/allwinner-a10-pit.h4
-rw-r--r--include/hw/timer/aspeed_timer.h5
-rw-r--r--include/hw/timer/hpet.h5
-rw-r--r--include/hw/timer/i8254.h10
-rw-r--r--include/hw/timer/i8254_internal.h10
-rw-r--r--include/hw/timer/imx_gpt.h9
-rw-r--r--include/hw/timer/m48t59.h6
-rw-r--r--include/hw/timer/mc146818rtc.h2
-rw-r--r--include/hw/timer/mc146818rtc_regs.h5
-rw-r--r--include/hw/timer/mips_gictimer.h46
-rw-r--r--include/hw/tricore/tricore.h4
-rw-r--r--include/hw/unicore32/puv3.h3
-rw-r--r--include/hw/usb.h3
-rw-r--r--include/hw/usb/ehci-regs.h2
-rw-r--r--include/hw/usb/uhci-regs.h2
-rw-r--r--include/hw/vfio/vfio-common.h26
-rw-r--r--include/hw/vfio/vfio-platform.h2
-rw-r--r--include/hw/vfio/vfio.h4
-rw-r--r--include/hw/virtio/vhost-backend.h10
-rw-r--r--include/hw/virtio/vhost.h7
-rw-r--r--include/hw/virtio/virtio-access.h14
-rw-r--r--include/hw/virtio/virtio-balloon.h4
-rw-r--r--include/hw/virtio/virtio-blk.h10
-rw-r--r--include/hw/virtio/virtio-bus.h31
-rw-r--r--include/hw/virtio/virtio-gpu.h19
-rw-r--r--include/hw/virtio/virtio-input.h6
-rw-r--r--include/hw/virtio/virtio-net.h4
-rw-r--r--include/hw/virtio/virtio-rng.h6
-rw-r--r--include/hw/virtio/virtio-scsi.h23
-rw-r--r--include/hw/virtio/virtio-serial.h5
-rw-r--r--include/hw/virtio/virtio.h33
-rw-r--r--include/hw/watchdog/wdt_diag288.h2
-rw-r--r--include/hw/xen/xen.h9
-rw-r--r--include/hw/xen/xen_backend.h9
-rw-r--r--include/hw/xen/xen_common.h131
-rw-r--r--include/io/channel-buffer.h6
-rw-r--r--include/io/channel-command.h6
-rw-r--r--include/io/channel-file.h6
-rw-r--r--include/io/channel-socket.h6
-rw-r--r--include/io/channel-tls.h6
-rw-r--r--include/io/channel-util.h6
-rw-r--r--include/io/channel-watch.h6
-rw-r--r--include/io/channel-websock.h6
-rw-r--r--include/io/channel.h7
-rw-r--r--include/io/task.h8
-rw-r--r--include/libdecnumber/decContext.h5
-rw-r--r--include/libdecnumber/decNumber.h9
-rw-r--r--include/libdecnumber/decNumberLocal.h7
-rw-r--r--include/libdecnumber/dpd/decimal128.h9
-rw-r--r--include/libdecnumber/dpd/decimal32.h9
-rw-r--r--include/libdecnumber/dpd/decimal64.h9
-rw-r--r--include/migration/block.h6
-rw-r--r--include/migration/cpu.h48
-rw-r--r--include/migration/migration.h30
-rw-r--r--include/migration/qemu-file.h61
-rw-r--r--include/migration/vmstate.h28
-rw-r--r--include/monitor/hmp-target.h7
-rw-r--r--include/monitor/monitor.h3
-rw-r--r--include/monitor/qdev.h4
-rw-r--r--include/net/checksum.h49
-rw-r--r--include/net/eth.h158
-rw-r--r--include/net/net.h26
-rw-r--r--include/net/vhost-user.h7
-rw-r--r--include/net/vhost_net.h4
-rw-r--r--include/qapi/clone-visitor.h39
-rw-r--r--include/qapi/dealloc-visitor.h10
-rw-r--r--include/qapi/error.h2
-rw-r--r--include/qapi/opts-visitor.h9
-rw-r--r--include/qapi/qmp-input-visitor.h13
-rw-r--r--include/qapi/qmp-output-visitor.h12
-rw-r--r--include/qapi/qmp/dispatch.h11
-rw-r--r--include/qapi/qmp/qerror.h3
-rw-r--r--include/qapi/qmp/types.h7
-rw-r--r--include/qapi/string-input-visitor.h10
-rw-r--r--include/qapi/string-output-visitor.h19
-rw-r--r--include/qapi/visitor-impl.h95
-rw-r--r--include/qapi/visitor.h563
-rw-r--r--include/qemu-common.h38
-rw-r--r--include/qemu/acl.h14
-rw-r--r--include/qemu/atomic.h87
-rw-r--r--include/qemu/base64.h6
-rw-r--r--include/qemu/bcd.h2
-rw-r--r--include/qemu/bitmap.h1
-rw-r--r--include/qemu/bitops.h111
-rw-r--r--include/qemu/bswap.h70
-rw-r--r--include/qemu/buffer.h6
-rw-r--r--include/qemu/compiler.h5
-rw-r--r--include/qemu/config-file.h7
-rw-r--r--include/qemu/coroutine.h10
-rw-r--r--include/qemu/coroutine_int.h4
-rw-r--r--include/qemu/cutils.h2
-rw-r--r--include/qemu/error-report.h5
-rw-r--r--include/qemu/fifo32.h190
-rw-r--r--include/qemu/fifo8.h6
-rw-r--r--include/qemu/fprintf-fn.h3
-rw-r--r--include/qemu/hbitmap.h2
-rw-r--r--include/qemu/help_option.h2
-rw-r--r--include/qemu/host-utils.h5
-rw-r--r--include/qemu/id.h2
-rw-r--r--include/qemu/log.h24
-rw-r--r--include/qemu/main-loop.h6
-rw-r--r--include/qemu/mmap-alloc.h4
-rw-r--r--include/qemu/option.h4
-rw-r--r--include/qemu/option_int.h4
-rw-r--r--include/qemu/osdep.h38
-rw-r--r--include/qemu/path.h2
-rw-r--r--include/qemu/processor.h30
-rw-r--r--include/qemu/qdist.h62
-rw-r--r--include/qemu/qht.h187
-rw-r--r--include/qemu/queue.h6
-rw-r--r--include/qemu/range.h194
-rw-r--r--include/qemu/ratelimit.h45
-rw-r--r--include/qemu/rcu.h1
-rw-r--r--include/qemu/rcu_queue.h2
-rw-r--r--include/qemu/readline.h2
-rw-r--r--include/qemu/seqlock.h21
-rw-r--r--include/qemu/sockets.h33
-rw-r--r--include/qemu/thread-posix.h7
-rw-r--r--include/qemu/thread-win32.h7
-rw-r--r--include/qemu/thread.h39
-rw-r--r--include/qemu/timer.h1
-rw-r--r--include/qemu/typedefs.h1
-rw-r--r--include/qemu/unicode.h2
-rw-r--r--include/qjson.h (renamed from include/migration/qjson.h)2
-rw-r--r--include/qom/cpu.h66
-rw-r--r--include/qom/object.h11
-rw-r--r--include/standard-headers/linux/pci_regs.h20
-rw-r--r--include/standard-headers/linux/virtio_config.h2
-rw-r--r--include/sysemu/accel.h2
-rw-r--r--include/sysemu/arch_init.h1
-rw-r--r--include/sysemu/balloon.h4
-rw-r--r--include/sysemu/block-backend.h88
-rw-r--r--include/sysemu/bt.h4
-rw-r--r--include/sysemu/char.h39
-rw-r--r--include/sysemu/cpus.h13
-rw-r--r--include/sysemu/device_tree.h6
-rw-r--r--include/sysemu/dma.h23
-rw-r--r--include/sysemu/hostmem.h10
-rw-r--r--include/sysemu/kvm.h26
-rw-r--r--include/sysemu/os-posix.h1
-rw-r--r--include/sysemu/rng-random.h4
-rw-r--r--include/sysemu/sysemu.h16
-rw-r--r--include/sysemu/tpm_backend.h4
-rw-r--r--include/sysemu/tpm_backend_int.h8
-rw-r--r--include/sysemu/xen-mapcache.h3
-rw-r--r--include/trace-tcg.h2
-rw-r--r--include/trace.h2
-rw-r--r--include/ui/console.h66
-rw-r--r--include/ui/gtk.h2
-rw-r--r--include/ui/qemu-spice.h19
-rw-r--r--include/ui/sdl2.h1
-rw-r--r--io/channel-buffer.c1
-rw-r--r--io/channel-socket.c26
-rw-r--r--io/channel-websock.c1
-rw-r--r--io/channel.c2
-rw-r--r--io/trace-events63
-rw-r--r--ioport.c14
-rw-r--r--kvm-all.c106
-rw-r--r--kvm-stub.c12
-rw-r--r--linux-headers/asm-arm/unistd.h2
-rw-r--r--linux-headers/asm-arm64/unistd.h3
-rw-r--r--linux-headers/asm-powerpc/unistd.h2
-rw-r--r--linux-headers/asm-s390/kvm.h1
-rw-r--r--linux-headers/asm-s390/unistd.h4
-rw-r--r--linux-headers/asm-x86/kvm.h6
-rw-r--r--linux-headers/asm-x86/unistd_x32.h2
-rw-r--r--linux-headers/linux/kvm.h1
-rw-r--r--linux-user/Makefile.objs3
-rw-r--r--linux-user/aarch64/syscall_nr.h3
-rw-r--r--linux-user/aarch64/target_cpu.h4
-rw-r--r--linux-user/aarch64/target_signal.h6
-rw-r--r--linux-user/aarch64/target_structs.h4
-rw-r--r--linux-user/aarch64/target_syscall.h6
-rw-r--r--linux-user/alpha/target_cpu.h4
-rw-r--r--linux-user/alpha/target_signal.h7
-rw-r--r--linux-user/alpha/target_structs.h4
-rw-r--r--linux-user/alpha/target_syscall.h6
-rw-r--r--linux-user/arm/nwfpe/fpa11.h7
-rw-r--r--linux-user/arm/nwfpe/fpopcode.h4
-rw-r--r--linux-user/arm/nwfpe/fpsr.h4
-rw-r--r--linux-user/arm/target_cpu.h4
-rw-r--r--linux-user/arm/target_signal.h7
-rw-r--r--linux-user/arm/target_structs.h4
-rw-r--r--linux-user/arm/target_syscall.h26
-rw-r--r--linux-user/cris/target_cpu.h4
-rw-r--r--linux-user/cris/target_signal.h7
-rw-r--r--linux-user/cris/target_structs.h4
-rw-r--r--linux-user/cris/target_syscall.h4
-rw-r--r--linux-user/elfload.c20
-rw-r--r--linux-user/errno_defs.h17
-rw-r--r--linux-user/flatload.c3
-rw-r--r--linux-user/host/aarch64/hostdep.h38
-rw-r--r--linux-user/host/aarch64/safe-syscall.inc.S75
-rw-r--r--linux-user/host/arm/hostdep.h38
-rw-r--r--linux-user/host/arm/safe-syscall.inc.S90
-rw-r--r--linux-user/host/i386/hostdep.h38
-rw-r--r--linux-user/host/i386/safe-syscall.inc.S100
-rw-r--r--linux-user/host/ia64/hostdep.h15
-rw-r--r--linux-user/host/mips/hostdep.h15
-rw-r--r--linux-user/host/ppc/hostdep.h15
-rw-r--r--linux-user/host/ppc64/hostdep.h38
-rw-r--r--linux-user/host/ppc64/safe-syscall.inc.S92
-rw-r--r--linux-user/host/s390/hostdep.h15
-rw-r--r--linux-user/host/s390x/hostdep.h38
-rw-r--r--linux-user/host/s390x/safe-syscall.inc.S90
-rw-r--r--linux-user/host/sparc/hostdep.h15
-rw-r--r--linux-user/host/sparc64/hostdep.h15
-rw-r--r--linux-user/host/x32/hostdep.h15
-rw-r--r--linux-user/host/x86_64/hostdep.h38
-rw-r--r--linux-user/host/x86_64/safe-syscall.inc.S91
-rw-r--r--linux-user/i386/target_cpu.h6
-rw-r--r--linux-user/i386/target_signal.h6
-rw-r--r--linux-user/i386/target_structs.h4
-rw-r--r--linux-user/i386/target_syscall.h6
-rw-r--r--linux-user/ioctls.h41
-rw-r--r--linux-user/linux_loop.h16
-rw-r--r--linux-user/m68k/target_cpu.h4
-rw-r--r--linux-user/m68k/target_signal.h7
-rw-r--r--linux-user/m68k/target_structs.h4
-rw-r--r--linux-user/m68k/target_syscall.h6
-rw-r--r--linux-user/main.c313
-rw-r--r--linux-user/microblaze/target_cpu.h4
-rw-r--r--linux-user/microblaze/target_signal.h7
-rw-r--r--linux-user/microblaze/target_structs.h4
-rw-r--r--linux-user/microblaze/target_syscall.h4
-rw-r--r--linux-user/mips/target_cpu.h4
-rw-r--r--linux-user/mips/target_signal.h7
-rw-r--r--linux-user/mips/target_structs.h4
-rw-r--r--linux-user/mips/target_syscall.h10
-rw-r--r--linux-user/mips64/target_signal.h7
-rw-r--r--linux-user/mips64/target_syscall.h10
-rw-r--r--linux-user/mmap.c1
-rw-r--r--linux-user/openrisc/target_cpu.h4
-rw-r--r--linux-user/openrisc/target_signal.h7
-rw-r--r--linux-user/openrisc/target_structs.h4
-rw-r--r--linux-user/openrisc/target_syscall.h6
-rw-r--r--linux-user/ppc/target_cpu.h4
-rw-r--r--linux-user/ppc/target_signal.h7
-rw-r--r--linux-user/ppc/target_structs.h4
-rw-r--r--linux-user/ppc/target_syscall.h8
-rw-r--r--linux-user/qemu.h205
-rw-r--r--linux-user/s390x/target_cpu.h4
-rw-r--r--linux-user/s390x/target_signal.h7
-rw-r--r--linux-user/s390x/target_structs.h4
-rw-r--r--linux-user/s390x/target_syscall.h6
-rw-r--r--linux-user/safe-syscall.S30
-rw-r--r--linux-user/sh4/target_cpu.h4
-rw-r--r--linux-user/sh4/target_signal.h7
-rw-r--r--linux-user/sh4/target_structs.h4
-rw-r--r--linux-user/sh4/target_syscall.h6
-rw-r--r--linux-user/signal.c2210
-rw-r--r--linux-user/sparc/syscall_nr.h3
-rw-r--r--linux-user/sparc/target_cpu.h4
-rw-r--r--linux-user/sparc/target_signal.h7
-rw-r--r--linux-user/sparc/target_structs.h4
-rw-r--r--linux-user/sparc/target_syscall.h6
-rw-r--r--linux-user/sparc64/target_signal.h7
-rw-r--r--linux-user/sparc64/target_structs.h4
-rw-r--r--linux-user/sparc64/target_syscall.h6
-rw-r--r--linux-user/strace.c626
-rw-r--r--linux-user/strace.list10
-rw-r--r--linux-user/syscall.c2310
-rw-r--r--linux-user/syscall_defs.h98
-rw-r--r--linux-user/syscall_types.h9
-rw-r--r--linux-user/tilegx/syscall_nr.h4
-rw-r--r--linux-user/tilegx/target_cpu.h4
-rw-r--r--linux-user/tilegx/target_signal.h7
-rw-r--r--linux-user/tilegx/target_structs.h4
-rw-r--r--linux-user/tilegx/target_syscall.h4
-rw-r--r--linux-user/trace-events12
-rw-r--r--linux-user/uname.h4
-rw-r--r--linux-user/unicore32/target_cpu.h4
-rw-r--r--linux-user/unicore32/target_signal.h6
-rw-r--r--linux-user/unicore32/target_structs.h4
-rw-r--r--linux-user/unicore32/target_syscall.h8
-rw-r--r--linux-user/x86_64/target_signal.h6
-rw-r--r--linux-user/x86_64/target_structs.h19
-rw-r--r--linux-user/x86_64/target_syscall.h6
-rw-r--r--linux-user/x86_64/termbits.h12
-rw-r--r--main-loop.c2
-rw-r--r--memory.c121
-rw-r--r--memory_mapping.c1
-rw-r--r--migration/Makefile.objs8
-rw-r--r--migration/block.c149
-rw-r--r--migration/exec.c62
-rw-r--r--migration/fd.c75
-rw-r--r--migration/migration.c282
-rw-r--r--migration/postcopy-ram.c8
-rw-r--r--migration/qemu-file-buf.c464
-rw-r--r--migration/qemu-file-channel.c180
-rw-r--r--migration/qemu-file-internal.h (renamed from include/hw/dma/xlnx-zynq-devcfg.h)53
-rw-r--r--migration/qemu-file-stdio.c196
-rw-r--r--migration/qemu-file-unix.c323
-rw-r--r--migration/qemu-file.c134
-rw-r--r--migration/ram.c270
-rw-r--r--migration/rdma.c384
-rw-r--r--migration/savevm.c226
-rw-r--r--migration/socket.c185
-rw-r--r--migration/tcp.c102
-rw-r--r--migration/tls.c161
-rw-r--r--migration/trace-events209
-rw-r--r--migration/unix.c103
-rw-r--r--migration/vmstate.c14
-rw-r--r--monitor.c129
-rw-r--r--nbd/client.c51
-rw-r--r--nbd/common.c5
-rw-r--r--nbd/nbd-internal.h5
-rw-r--r--nbd/server.c173
-rw-r--r--net/checksum.c128
-rw-r--r--net/clients.h20
-rw-r--r--net/dump.c8
-rw-r--r--net/eth.c410
-rw-r--r--net/filter-mirror.c66
-rw-r--r--net/filter.c2
-rw-r--r--net/hub.c24
-rw-r--r--net/l2tpv3.c8
-rw-r--r--net/net.c264
-rw-r--r--net/netmap.c7
-rw-r--r--net/slirp.c21
-rw-r--r--net/socket.c87
-rw-r--r--net/tap-linux.h2
-rw-r--r--net/tap-win32.c8
-rw-r--r--net/tap.c87
-rw-r--r--net/tap_int.h6
-rw-r--r--net/trace-events4
-rw-r--r--net/vde.c8
-rw-r--r--net/vhost-user.c105
-rw-r--r--numa.c22
-rw-r--r--os-posix.c4
-rw-r--r--page_cache.c7
-rw-r--r--pc-bios/bios-256k.binbin262144 -> 262144 bytes
-rw-r--r--pc-bios/bios.binbin131072 -> 131072 bytes
-rw-r--r--pc-bios/efi-e1000.rombin209408 -> 196608 bytes
-rw-r--r--pc-bios/efi-e1000e.rombin209408 -> 0 bytes
-rw-r--r--pc-bios/efi-eepro100.rombin209920 -> 197120 bytes
-rw-r--r--pc-bios/efi-ne2k_pci.rombin208384 -> 195584 bytes
-rw-r--r--pc-bios/efi-pcnet.rombin208384 -> 195584 bytes
-rw-r--r--pc-bios/efi-rtl8139.rombin211456 -> 199168 bytes
-rw-r--r--pc-bios/efi-virtio.rombin211456 -> 193024 bytes
-rw-r--r--pc-bios/efi-vmxnet3.rombin205312 -> 0 bytes
-rw-r--r--pc-bios/linuxboot_dma.binbin1536 -> 0 bytes
-rw-r--r--pc-bios/openbios-ppcbin750840 -> 750684 bytes
-rw-r--r--pc-bios/openbios-sparc32bin381584 -> 381584 bytes
-rw-r--r--pc-bios/openbios-sparc64bin1592280 -> 1592280 bytes
-rw-r--r--pc-bios/optionrom/Makefile41
-rw-r--r--pc-bios/optionrom/code16gcc.h3
-rw-r--r--pc-bios/optionrom/flat.lds6
-rw-r--r--pc-bios/optionrom/linuxboot_dma.c298
-rw-r--r--pc-bios/s390-ccw.imgbin26440 -> 26424 bytes
-rw-r--r--pc-bios/s390-ccw/Makefile6
-rw-r--r--pc-bios/s390-ccw/iplb.h91
-rw-r--r--pc-bios/s390-ccw/main.c37
-rw-r--r--pc-bios/s390-ccw/s390-ccw.h2
-rw-r--r--pc-bios/s390-ccw/start.S2
-rw-r--r--pc-bios/s390-ccw/virtio-scsi.c11
-rw-r--r--pc-bios/s390-ccw/virtio.h2
-rw-r--r--po/Makefile2
-rw-r--r--po/bg.po90
-rw-r--r--qapi-schema.json252
-rw-r--r--qapi/Makefile.objs2
-rw-r--r--qapi/block-core.json245
-rw-r--r--qapi/crypto.json93
-rw-r--r--qapi/opts-visitor.c106
-rw-r--r--qapi/qapi-clone-visitor.c182
-rw-r--r--qapi/qapi-dealloc-visitor.c102
-rw-r--r--qapi/qapi-visit-core.c144
-rw-r--r--qapi/qmp-dispatch.c19
-rw-r--r--qapi/qmp-input-visitor.c225
-rw-r--r--qapi/qmp-output-visitor.c123
-rw-r--r--qapi/qmp-registry.c2
-rw-r--r--qapi/string-input-visitor.c109
-rw-r--r--qapi/string-output-visitor.c97
-rw-r--r--qapi/trace.json33
-rw-r--r--qemu-bridge-helper.c1
-rw-r--r--qemu-char.c205
-rw-r--r--qemu-doc.texi3
-rw-r--r--qemu-img-cmds.hx6
-rw-r--r--qemu-img.c488
-rw-r--r--qemu-img.texi37
-rw-r--r--qemu-io-cmds.c526
-rw-r--r--qemu-io.c63
-rw-r--r--qemu-nbd.c38
-rw-r--r--qemu-nbd.texi3
-rw-r--r--qemu-option-trace.texi25
-rw-r--r--qemu-options.h4
-rw-r--r--qemu-options.hx87
-rw-r--r--qemu-timer.c2
-rw-r--r--qga/channel-posix.c1
-rw-r--r--qga/channel-win32.c1
-rw-r--r--qga/channel.h1
-rw-r--r--qga/commands-posix.c17
-rw-r--r--qga/commands-win32.c14
-rw-r--r--qga/commands.c1
-rw-r--r--qga/guest-agent-command-state.c1
-rw-r--r--qga/main.c1
-rw-r--r--qga/service-win32.c1
-rw-r--r--qga/service-win32.h5
-rw-r--r--qga/vss-win32/install.cpp3
-rw-r--r--qga/vss-win32/provider.cpp4
-rw-r--r--qga/vss-win32/requester.cpp4
-rw-r--r--qga/vss-win32/vss-common.h6
-rw-r--r--qjson.c (renamed from migration/qjson.c)59
-rw-r--r--qmp-commands.hx205
-rw-r--r--qmp.c14
-rw-r--r--qobject/json-lexer.c19
-rw-r--r--qobject/json-parser.c7
-rw-r--r--qobject/qdict.c15
-rw-r--r--qobject/qjson.c6
-rw-r--r--qobject/qlist.c5
-rw-r--r--qobject/qobject.c7
-rw-r--r--qom/cpu.c43
-rw-r--r--qom/object.c73
-rw-r--r--qom/object_interfaces.c48
-rw-r--r--qom/qom-qobject.c20
-rw-r--r--qom/trace-events5
-rw-r--r--qtest.c2
-rwxr-xr-xreplay/replay-char.c4
-rw-r--r--replay/replay-input.c34
-rw-r--r--roms/Makefile8
-rw-r--r--roms/config.seabios-128k2
-rw-r--r--roms/ipxe/src/Makefile15
-rw-r--r--roms/ipxe/src/Makefile.efi46
-rw-r--r--roms/ipxe/src/Makefile.housekeeping33
-rw-r--r--roms/ipxe/src/arch/arm/Makefile12
-rw-r--r--roms/ipxe/src/arch/arm/Makefile.efi6
-rw-r--r--roms/ipxe/src/arch/arm/core/arm_io.c93
-rw-r--r--roms/ipxe/src/arch/arm/include/bits/endian.h13
-rw-r--r--roms/ipxe/src/arch/arm/include/bits/errfile.h19
-rw-r--r--roms/ipxe/src/arch/arm/include/bits/hyperv.h12
-rw-r--r--roms/ipxe/src/arch/arm/include/bits/io.h14
-rw-r--r--roms/ipxe/src/arch/arm/include/bits/iomap.h12
-rw-r--r--roms/ipxe/src/arch/arm/include/bits/nap.h14
-rw-r--r--roms/ipxe/src/arch/arm/include/bits/pci_io.h14
-rw-r--r--roms/ipxe/src/arch/arm/include/bits/uart.h12
-rw-r--r--roms/ipxe/src/arch/arm/include/bits/umalloc.h12
-rw-r--r--roms/ipxe/src/arch/arm/include/bits/xen.h158
-rw-r--r--roms/ipxe/src/arch/arm/include/ipxe/arm_io.h105
-rw-r--r--roms/ipxe/src/arch/arm/include/ipxe/efi/efiarm_nap.h18
-rw-r--r--roms/ipxe/src/arch/arm/interface/efi/efiarm_nap.c53
-rw-r--r--roms/ipxe/src/arch/arm32/Makefile23
-rw-r--r--roms/ipxe/src/arch/arm32/Makefile.efi14
-rw-r--r--roms/ipxe/src/arch/arm32/core/arm32_bigint.c102
-rw-r--r--roms/ipxe/src/arch/arm32/core/setjmp.S32
-rw-r--r--roms/ipxe/src/arch/arm32/include/bits/bigint.h316
-rw-r--r--roms/ipxe/src/arch/arm32/include/bits/bitops.h100
-rw-r--r--roms/ipxe/src/arch/arm32/include/bits/byteswap.h52
-rw-r--r--roms/ipxe/src/arch/arm32/include/bits/compiler.h16
-rw-r--r--roms/ipxe/src/arch/arm32/include/bits/profile.h30
-rw-r--r--roms/ipxe/src/arch/arm32/include/bits/stdint.h23
-rw-r--r--roms/ipxe/src/arch/arm32/include/bits/string.h60
-rw-r--r--roms/ipxe/src/arch/arm32/include/bits/strings.h85
-rw-r--r--roms/ipxe/src/arch/arm32/include/bits/tcpip.h19
-rw-r--r--roms/ipxe/src/arch/arm32/include/efi/ipxe/dhcp_arch.h46
-rw-r--r--roms/ipxe/src/arch/arm32/include/gdbmach.h45
-rw-r--r--roms/ipxe/src/arch/arm32/include/limits.h61
-rw-r--r--roms/ipxe/src/arch/arm32/include/setjmp.h38
-rw-r--r--roms/ipxe/src/arch/arm32/libgcc/lldivmod.S50
-rw-r--r--roms/ipxe/src/arch/arm32/libgcc/llshift.S88
-rw-r--r--roms/ipxe/src/arch/arm64/Makefile22
-rw-r--r--roms/ipxe/src/arch/arm64/Makefile.efi14
-rw-r--r--roms/ipxe/src/arch/arm64/core/arm64_bigint.c103
-rw-r--r--roms/ipxe/src/arch/arm64/core/arm64_string.c249
-rw-r--r--roms/ipxe/src/arch/arm64/core/arm64_tcpip.c175
-rw-r--r--roms/ipxe/src/arch/arm64/core/setjmp.S56
-rw-r--r--roms/ipxe/src/arch/arm64/include/bits/bigint.h317
-rw-r--r--roms/ipxe/src/arch/arm64/include/bits/bitops.h100
-rw-r--r--roms/ipxe/src/arch/arm64/include/bits/byteswap.h47
-rw-r--r--roms/ipxe/src/arch/arm64/include/bits/compiler.h16
-rw-r--r--roms/ipxe/src/arch/arm64/include/bits/profile.h28
-rw-r--r--roms/ipxe/src/arch/arm64/include/bits/stdint.h21
-rw-r--r--roms/ipxe/src/arch/arm64/include/bits/string.h106
-rw-r--r--roms/ipxe/src/arch/arm64/include/bits/strings.h69
-rw-r--r--roms/ipxe/src/arch/arm64/include/bits/tcpip.h15
-rw-r--r--roms/ipxe/src/arch/arm64/include/efi/ipxe/dhcp_arch.h46
-rw-r--r--roms/ipxe/src/arch/arm64/include/gdbmach.h45
-rw-r--r--roms/ipxe/src/arch/arm64/include/limits.h59
-rw-r--r--roms/ipxe/src/arch/arm64/include/setjmp.h44
-rw-r--r--roms/ipxe/src/arch/i386/Makefile28
-rw-r--r--roms/ipxe/src/arch/i386/Makefile.efi4
-rw-r--r--roms/ipxe/src/arch/i386/Makefile.pcbios100
-rw-r--r--roms/ipxe/src/arch/i386/core/basemem_packet.c (renamed from roms/ipxe/src/arch/x86/core/basemem_packet.c)0
-rw-r--r--roms/ipxe/src/arch/i386/core/cachedhcp.c (renamed from roms/ipxe/src/arch/x86/core/cachedhcp.c)15
-rw-r--r--roms/ipxe/src/arch/i386/core/dumpregs.c (renamed from roms/ipxe/src/arch/x86/core/dumpregs.c)7
-rw-r--r--roms/ipxe/src/arch/i386/core/gdbidt.S28
-rw-r--r--roms/ipxe/src/arch/i386/core/gdbmach.c184
-rw-r--r--roms/ipxe/src/arch/i386/core/patch_cf.S (renamed from roms/ipxe/src/arch/x86/core/patch_cf.S)0
-rw-r--r--roms/ipxe/src/arch/i386/core/pci_autoboot.c (renamed from roms/ipxe/src/arch/x86/core/pci_autoboot.c)0
-rw-r--r--roms/ipxe/src/arch/i386/core/rdtsc_timer.c (renamed from roms/ipxe/src/arch/x86/core/rdtsc_timer.c)0
-rw-r--r--roms/ipxe/src/arch/i386/core/relocate.c (renamed from roms/ipxe/src/arch/x86/core/relocate.c)42
-rw-r--r--roms/ipxe/src/arch/i386/core/runtime.c (renamed from roms/ipxe/src/arch/x86/core/runtime.c)0
-rw-r--r--roms/ipxe/src/arch/i386/core/stack.S (renamed from roms/ipxe/src/arch/x86/core/stack.S)8
-rw-r--r--roms/ipxe/src/arch/i386/core/stack16.S (renamed from roms/ipxe/src/arch/x86/core/stack16.S)0
-rw-r--r--roms/ipxe/src/arch/i386/core/video_subr.c (renamed from roms/ipxe/src/arch/x86/core/video_subr.c)0
-rw-r--r--roms/ipxe/src/arch/i386/core/virtaddr.S145
-rw-r--r--roms/ipxe/src/arch/i386/drivers/net/undi.c (renamed from roms/ipxe/src/arch/x86/drivers/net/undi.c)0
-rw-r--r--roms/ipxe/src/arch/i386/drivers/net/undiisr.S (renamed from roms/ipxe/src/arch/x86/drivers/net/undiisr.S)0
-rw-r--r--roms/ipxe/src/arch/i386/drivers/net/undiload.c (renamed from roms/ipxe/src/arch/x86/drivers/net/undiload.c)0
-rw-r--r--roms/ipxe/src/arch/i386/drivers/net/undinet.c (renamed from roms/ipxe/src/arch/x86/drivers/net/undinet.c)8
-rw-r--r--roms/ipxe/src/arch/i386/drivers/net/undionly.c (renamed from roms/ipxe/src/arch/x86/drivers/net/undionly.c)0
-rw-r--r--roms/ipxe/src/arch/i386/drivers/net/undipreload.c (renamed from roms/ipxe/src/arch/x86/drivers/net/undipreload.c)0
-rw-r--r--roms/ipxe/src/arch/i386/drivers/net/undirom.c (renamed from roms/ipxe/src/arch/x86/drivers/net/undirom.c)0
-rw-r--r--roms/ipxe/src/arch/i386/firmware/pcbios/basemem.c (renamed from roms/ipxe/src/arch/x86/interface/pcbios/basemem.c)0
-rw-r--r--roms/ipxe/src/arch/i386/firmware/pcbios/bios_console.c (renamed from roms/ipxe/src/arch/x86/interface/pcbios/bios_console.c)245
-rw-r--r--roms/ipxe/src/arch/i386/firmware/pcbios/e820mangler.S (renamed from roms/ipxe/src/arch/x86/interface/pcbios/e820mangler.S)0
-rw-r--r--roms/ipxe/src/arch/i386/firmware/pcbios/fakee820.c (renamed from roms/ipxe/src/arch/x86/interface/pcbios/fakee820.c)4
-rw-r--r--roms/ipxe/src/arch/i386/firmware/pcbios/hidemem.c (renamed from roms/ipxe/src/arch/x86/interface/pcbios/hidemem.c)9
-rw-r--r--roms/ipxe/src/arch/i386/firmware/pcbios/memmap.c (renamed from roms/ipxe/src/arch/x86/interface/pcbios/memmap.c)6
-rw-r--r--roms/ipxe/src/arch/i386/firmware/pcbios/pnpbios.c (renamed from roms/ipxe/src/arch/x86/interface/pcbios/pnpbios.c)0
-rw-r--r--roms/ipxe/src/arch/i386/hci/commands/pxe_cmd.c (renamed from roms/ipxe/src/arch/x86/hci/commands/pxe_cmd.c)0
-rw-r--r--roms/ipxe/src/arch/i386/image/bootsector.c (renamed from roms/ipxe/src/arch/x86/image/bootsector.c)8
-rw-r--r--roms/ipxe/src/arch/i386/image/bzimage.c (renamed from roms/ipxe/src/arch/x86/image/bzimage.c)6
-rw-r--r--roms/ipxe/src/arch/i386/image/com32.c (renamed from roms/ipxe/src/arch/x86/image/com32.c)76
-rw-r--r--roms/ipxe/src/arch/i386/image/comboot.c (renamed from roms/ipxe/src/arch/x86/image/comboot.c)16
-rw-r--r--roms/ipxe/src/arch/i386/image/elfboot.c (renamed from roms/ipxe/src/arch/x86/image/elfboot.c)0
-rw-r--r--roms/ipxe/src/arch/i386/image/initrd.c (renamed from roms/ipxe/src/arch/x86/image/initrd.c)0
-rw-r--r--roms/ipxe/src/arch/i386/image/multiboot.c (renamed from roms/ipxe/src/arch/x86/image/multiboot.c)0
-rw-r--r--roms/ipxe/src/arch/i386/image/nbi.c (renamed from roms/ipxe/src/arch/x86/image/nbi.c)4
-rw-r--r--roms/ipxe/src/arch/i386/image/pxe_image.c (renamed from roms/ipxe/src/arch/x86/image/pxe_image.c)3
-rw-r--r--roms/ipxe/src/arch/i386/image/sdi.c (renamed from roms/ipxe/src/arch/x86/image/sdi.c)0
-rw-r--r--roms/ipxe/src/arch/i386/include/basemem.h (renamed from roms/ipxe/src/arch/x86/include/basemem.h)0
-rw-r--r--roms/ipxe/src/arch/i386/include/basemem_packet.h (renamed from roms/ipxe/src/arch/x86/include/basemem_packet.h)0
-rw-r--r--roms/ipxe/src/arch/i386/include/bios.h (renamed from roms/ipxe/src/arch/x86/include/bios.h)0
-rw-r--r--roms/ipxe/src/arch/i386/include/bios_disks.h (renamed from roms/ipxe/src/arch/x86/include/bios_disks.h)0
-rw-r--r--roms/ipxe/src/arch/i386/include/biosint.h (renamed from roms/ipxe/src/arch/x86/include/biosint.h)1
-rw-r--r--roms/ipxe/src/arch/i386/include/bits/compiler.h2
-rw-r--r--roms/ipxe/src/arch/i386/include/bits/entropy.h (renamed from roms/ipxe/src/arch/x86/include/bits/entropy.h)2
-rw-r--r--roms/ipxe/src/arch/i386/include/bits/hyperv.h23
-rw-r--r--roms/ipxe/src/arch/i386/include/bits/nap.h (renamed from roms/ipxe/src/arch/x86/include/bits/nap.h)2
-rw-r--r--roms/ipxe/src/arch/i386/include/bits/reboot.h (renamed from roms/ipxe/src/arch/x86/include/bits/reboot.h)2
-rw-r--r--roms/ipxe/src/arch/i386/include/bits/sanboot.h (renamed from roms/ipxe/src/arch/x86/include/bits/sanboot.h)2
-rw-r--r--roms/ipxe/src/arch/i386/include/bits/smbios.h (renamed from roms/ipxe/src/arch/x86/include/bits/smbios.h)2
-rw-r--r--roms/ipxe/src/arch/i386/include/bits/time.h (renamed from roms/ipxe/src/arch/x86/include/bits/time.h)2
-rw-r--r--roms/ipxe/src/arch/i386/include/bits/timer.h (renamed from roms/ipxe/src/arch/x86/include/bits/timer.h)2
-rw-r--r--roms/ipxe/src/arch/i386/include/bits/uaccess.h (renamed from roms/ipxe/src/arch/x86/include/bits/uaccess.h)2
-rw-r--r--roms/ipxe/src/arch/i386/include/bits/umalloc.h (renamed from roms/ipxe/src/arch/x86/include/bits/umalloc.h)2
-rw-r--r--roms/ipxe/src/arch/i386/include/bochs.h (renamed from roms/ipxe/src/arch/x86/include/bochs.h)0
-rw-r--r--roms/ipxe/src/arch/i386/include/bootsector.h (renamed from roms/ipxe/src/arch/x86/include/bootsector.h)0
-rw-r--r--roms/ipxe/src/arch/i386/include/bzimage.h (renamed from roms/ipxe/src/arch/x86/include/bzimage.h)0
-rw-r--r--roms/ipxe/src/arch/i386/include/comboot.h (renamed from roms/ipxe/src/arch/x86/include/comboot.h)8
-rw-r--r--roms/ipxe/src/arch/i386/include/fakee820.h (renamed from roms/ipxe/src/arch/x86/include/fakee820.h)0
-rw-r--r--roms/ipxe/src/arch/i386/include/gdbmach.h10
-rw-r--r--roms/ipxe/src/arch/i386/include/initrd.h (renamed from roms/ipxe/src/arch/x86/include/initrd.h)0
-rw-r--r--roms/ipxe/src/arch/i386/include/int13.h (renamed from roms/ipxe/src/arch/x86/include/int13.h)0
-rw-r--r--roms/ipxe/src/arch/i386/include/ipxe/bios_nap.h (renamed from roms/ipxe/src/arch/x86/include/ipxe/bios_nap.h)0
-rw-r--r--roms/ipxe/src/arch/i386/include/ipxe/bios_reboot.h (renamed from roms/ipxe/src/arch/x86/include/ipxe/bios_reboot.h)0
-rw-r--r--roms/ipxe/src/arch/i386/include/ipxe/bios_sanboot.h (renamed from roms/ipxe/src/arch/x86/include/ipxe/bios_sanboot.h)11
-rw-r--r--roms/ipxe/src/arch/i386/include/ipxe/bios_smbios.h (renamed from roms/ipxe/src/arch/x86/include/ipxe/bios_smbios.h)0
-rw-r--r--roms/ipxe/src/arch/i386/include/ipxe/bios_timer.h (renamed from roms/ipxe/src/arch/x86/include/ipxe/bios_timer.h)0
-rw-r--r--roms/ipxe/src/arch/i386/include/ipxe/errno/pcbios.h (renamed from roms/ipxe/src/arch/x86/include/ipxe/errno/pcbios.h)0
-rw-r--r--roms/ipxe/src/arch/i386/include/ipxe/guestrpc.h (renamed from roms/ipxe/src/arch/x86/include/ipxe/guestrpc.h)0
-rw-r--r--roms/ipxe/src/arch/i386/include/ipxe/memtop_umalloc.h (renamed from roms/ipxe/src/arch/x86/include/ipxe/memtop_umalloc.h)0
-rw-r--r--roms/ipxe/src/arch/i386/include/ipxe/rdtsc_timer.h (renamed from roms/ipxe/src/arch/x86/include/ipxe/rdtsc_timer.h)0
-rw-r--r--roms/ipxe/src/arch/i386/include/ipxe/rtc_entropy.h (renamed from roms/ipxe/src/arch/x86/include/ipxe/rtc_entropy.h)0
-rw-r--r--roms/ipxe/src/arch/i386/include/ipxe/rtc_time.h (renamed from roms/ipxe/src/arch/x86/include/ipxe/rtc_time.h)0
-rw-r--r--roms/ipxe/src/arch/i386/include/ipxe/vesafb.h (renamed from roms/ipxe/src/arch/x86/include/ipxe/vesafb.h)0
-rw-r--r--roms/ipxe/src/arch/i386/include/ipxe/vmware.h (renamed from roms/ipxe/src/arch/x86/include/ipxe/vmware.h)0
-rw-r--r--roms/ipxe/src/arch/i386/include/kir.h (renamed from roms/ipxe/src/arch/x86/include/kir.h)0
-rw-r--r--roms/ipxe/src/arch/i386/include/libkir.h (renamed from roms/ipxe/src/arch/x86/include/libkir.h)0
-rw-r--r--roms/ipxe/src/arch/i386/include/librm.h (renamed from roms/ipxe/src/arch/x86/include/librm.h)211
-rw-r--r--roms/ipxe/src/arch/i386/include/memsizes.h (renamed from roms/ipxe/src/arch/x86/include/memsizes.h)0
-rw-r--r--roms/ipxe/src/arch/i386/include/multiboot.h (renamed from roms/ipxe/src/arch/x86/include/multiboot.h)0
-rw-r--r--roms/ipxe/src/arch/i386/include/pnpbios.h (renamed from roms/ipxe/src/arch/x86/include/pnpbios.h)0
-rw-r--r--roms/ipxe/src/arch/i386/include/pxe.h (renamed from roms/ipxe/src/arch/x86/include/pxe.h)1
-rw-r--r--roms/ipxe/src/arch/i386/include/pxe_api.h (renamed from roms/ipxe/src/arch/x86/include/pxe_api.h)0
-rw-r--r--roms/ipxe/src/arch/i386/include/pxe_call.h (renamed from roms/ipxe/src/arch/x86/include/pxe_call.h)2
-rw-r--r--roms/ipxe/src/arch/i386/include/pxe_error.h (renamed from roms/ipxe/src/arch/x86/include/pxe_error.h)0
-rw-r--r--roms/ipxe/src/arch/i386/include/pxe_types.h (renamed from roms/ipxe/src/arch/x86/include/pxe_types.h)0
-rw-r--r--roms/ipxe/src/arch/i386/include/pxeparent.h (renamed from roms/ipxe/src/arch/x86/include/pxeparent.h)0
-rw-r--r--roms/ipxe/src/arch/i386/include/realmode.h (renamed from roms/ipxe/src/arch/x86/include/realmode.h)0
-rw-r--r--roms/ipxe/src/arch/i386/include/registers.h (renamed from roms/ipxe/src/arch/x86/include/registers.h)2
-rw-r--r--roms/ipxe/src/arch/i386/include/rtc.h (renamed from roms/ipxe/src/arch/x86/include/rtc.h)0
-rw-r--r--roms/ipxe/src/arch/i386/include/sdi.h (renamed from roms/ipxe/src/arch/x86/include/sdi.h)0
-rw-r--r--roms/ipxe/src/arch/i386/include/setjmp.h20
-rw-r--r--roms/ipxe/src/arch/i386/include/undi.h (renamed from roms/ipxe/src/arch/x86/include/undi.h)0
-rw-r--r--roms/ipxe/src/arch/i386/include/undiload.h (renamed from roms/ipxe/src/arch/x86/include/undiload.h)0
-rw-r--r--roms/ipxe/src/arch/i386/include/undinet.h (renamed from roms/ipxe/src/arch/x86/include/undinet.h)0
-rw-r--r--roms/ipxe/src/arch/i386/include/undipreload.h (renamed from roms/ipxe/src/arch/x86/include/undipreload.h)0
-rw-r--r--roms/ipxe/src/arch/i386/include/undirom.h (renamed from roms/ipxe/src/arch/x86/include/undirom.h)0
-rw-r--r--roms/ipxe/src/arch/i386/include/vga.h (renamed from roms/ipxe/src/arch/x86/include/vga.h)0
-rw-r--r--roms/ipxe/src/arch/i386/interface/pcbios/apm.c (renamed from roms/ipxe/src/arch/x86/interface/pcbios/apm.c)0
-rw-r--r--roms/ipxe/src/arch/i386/interface/pcbios/bios_nap.c (renamed from roms/ipxe/src/arch/x86/interface/pcbios/bios_nap.c)0
-rw-r--r--roms/ipxe/src/arch/i386/interface/pcbios/bios_reboot.c (renamed from roms/ipxe/src/arch/x86/interface/pcbios/bios_reboot.c)2
-rw-r--r--roms/ipxe/src/arch/i386/interface/pcbios/bios_smbios.c (renamed from roms/ipxe/src/arch/x86/interface/pcbios/bios_smbios.c)0
-rw-r--r--roms/ipxe/src/arch/i386/interface/pcbios/bios_timer.c (renamed from roms/ipxe/src/arch/x86/interface/pcbios/bios_timer.c)0
-rw-r--r--roms/ipxe/src/arch/i386/interface/pcbios/biosint.c (renamed from roms/ipxe/src/arch/x86/interface/pcbios/biosint.c)27
-rw-r--r--roms/ipxe/src/arch/i386/interface/pcbios/int13.c (renamed from roms/ipxe/src/arch/x86/interface/pcbios/int13.c)49
-rw-r--r--roms/ipxe/src/arch/i386/interface/pcbios/int13con.c (renamed from roms/ipxe/src/arch/x86/interface/pcbios/int13con.c)0
-rw-r--r--roms/ipxe/src/arch/i386/interface/pcbios/memtop_umalloc.c (renamed from roms/ipxe/src/arch/x86/interface/pcbios/memtop_umalloc.c)53
-rw-r--r--roms/ipxe/src/arch/i386/interface/pcbios/pcibios.c (renamed from roms/ipxe/src/arch/x86/interface/pcbios/pcibios.c)8
-rw-r--r--roms/ipxe/src/arch/i386/interface/pcbios/rtc_entropy.c (renamed from roms/ipxe/src/arch/x86/interface/pcbios/rtc_entropy.c)36
-rw-r--r--roms/ipxe/src/arch/i386/interface/pcbios/rtc_time.c (renamed from roms/ipxe/src/arch/x86/interface/pcbios/rtc_time.c)0
-rw-r--r--roms/ipxe/src/arch/i386/interface/pcbios/vesafb.c (renamed from roms/ipxe/src/arch/x86/interface/pcbios/vesafb.c)66
-rw-r--r--roms/ipxe/src/arch/i386/interface/pxe/pxe_call.c (renamed from roms/ipxe/src/arch/x86/interface/pxe/pxe_call.c)62
-rw-r--r--roms/ipxe/src/arch/i386/interface/pxe/pxe_entry.S (renamed from roms/ipxe/src/arch/x86/interface/pxe/pxe_entry.S)7
-rw-r--r--roms/ipxe/src/arch/i386/interface/pxe/pxe_exit_hook.c (renamed from roms/ipxe/src/arch/x86/interface/pxe/pxe_exit_hook.c)0
-rw-r--r--roms/ipxe/src/arch/i386/interface/pxe/pxe_file.c (renamed from roms/ipxe/src/arch/x86/interface/pxe/pxe_file.c)0
-rw-r--r--roms/ipxe/src/arch/i386/interface/pxe/pxe_loader.c (renamed from roms/ipxe/src/arch/x86/interface/pxe/pxe_loader.c)0
-rw-r--r--roms/ipxe/src/arch/i386/interface/pxe/pxe_preboot.c (renamed from roms/ipxe/src/arch/x86/interface/pxe/pxe_preboot.c)60
-rw-r--r--roms/ipxe/src/arch/i386/interface/pxe/pxe_tftp.c (renamed from roms/ipxe/src/arch/x86/interface/pxe/pxe_tftp.c)24
-rw-r--r--roms/ipxe/src/arch/i386/interface/pxe/pxe_udp.c (renamed from roms/ipxe/src/arch/x86/interface/pxe/pxe_udp.c)10
-rw-r--r--roms/ipxe/src/arch/i386/interface/pxe/pxe_undi.c (renamed from roms/ipxe/src/arch/x86/interface/pxe/pxe_undi.c)0
-rw-r--r--roms/ipxe/src/arch/i386/interface/pxeparent/pxeparent.c (renamed from roms/ipxe/src/arch/x86/interface/pxeparent/pxeparent.c)12
-rw-r--r--roms/ipxe/src/arch/i386/interface/syslinux/com32_call.c (renamed from roms/ipxe/src/arch/x86/interface/syslinux/com32_call.c)17
-rw-r--r--roms/ipxe/src/arch/i386/interface/syslinux/com32_wrapper.S (renamed from roms/ipxe/src/arch/x86/interface/syslinux/com32_wrapper.S)99
-rw-r--r--roms/ipxe/src/arch/i386/interface/syslinux/comboot_call.c (renamed from roms/ipxe/src/arch/x86/interface/syslinux/comboot_call.c)48
-rw-r--r--roms/ipxe/src/arch/i386/interface/syslinux/comboot_resolv.c (renamed from roms/ipxe/src/arch/x86/interface/syslinux/comboot_resolv.c)0
-rw-r--r--roms/ipxe/src/arch/i386/interface/vmware/guestinfo.c (renamed from roms/ipxe/src/arch/x86/interface/vmware/guestinfo.c)0
-rw-r--r--roms/ipxe/src/arch/i386/interface/vmware/guestrpc.c (renamed from roms/ipxe/src/arch/x86/interface/vmware/guestrpc.c)0
-rw-r--r--roms/ipxe/src/arch/i386/interface/vmware/vmconsole.c (renamed from roms/ipxe/src/arch/x86/interface/vmware/vmconsole.c)0
-rw-r--r--roms/ipxe/src/arch/i386/interface/vmware/vmware.c (renamed from roms/ipxe/src/arch/x86/interface/vmware/vmware.c)0
-rw-r--r--roms/ipxe/src/arch/i386/prefix/bootpart.S (renamed from roms/ipxe/src/arch/x86/prefix/bootpart.S)0
-rw-r--r--roms/ipxe/src/arch/i386/prefix/dskprefix.S (renamed from roms/ipxe/src/arch/x86/prefix/dskprefix.S)8
-rw-r--r--roms/ipxe/src/arch/i386/prefix/exeprefix.S (renamed from roms/ipxe/src/arch/x86/prefix/exeprefix.S)7
-rw-r--r--roms/ipxe/src/arch/i386/prefix/hdprefix.S (renamed from roms/ipxe/src/arch/x86/prefix/hdprefix.S)8
-rw-r--r--roms/ipxe/src/arch/i386/prefix/isaromprefix.S (renamed from roms/ipxe/src/arch/x86/prefix/isaromprefix.S)0
-rw-r--r--roms/ipxe/src/arch/i386/prefix/kkkpxeprefix.S (renamed from roms/ipxe/src/arch/x86/prefix/kkkpxeprefix.S)0
-rw-r--r--roms/ipxe/src/arch/i386/prefix/kkpxeprefix.S (renamed from roms/ipxe/src/arch/x86/prefix/kkpxeprefix.S)0
-rw-r--r--roms/ipxe/src/arch/i386/prefix/kpxeprefix.S (renamed from roms/ipxe/src/arch/x86/prefix/kpxeprefix.S)0
-rw-r--r--roms/ipxe/src/arch/i386/prefix/libprefix.S (renamed from roms/ipxe/src/arch/x86/prefix/libprefix.S)174
-rw-r--r--roms/ipxe/src/arch/i386/prefix/lkrnprefix.S (renamed from roms/ipxe/src/arch/x86/prefix/lkrnprefix.S)7
-rw-r--r--roms/ipxe/src/arch/i386/prefix/mbr.S (renamed from roms/ipxe/src/arch/x86/prefix/mbr.S)0
-rw-r--r--roms/ipxe/src/arch/i386/prefix/mromprefix.S (renamed from roms/ipxe/src/arch/x86/prefix/mromprefix.S)0
-rw-r--r--roms/ipxe/src/arch/i386/prefix/nbiprefix.S (renamed from roms/ipxe/src/arch/x86/prefix/nbiprefix.S)8
-rw-r--r--roms/ipxe/src/arch/i386/prefix/nullprefix.S (renamed from roms/ipxe/src/arch/x86/prefix/nullprefix.S)0
-rw-r--r--roms/ipxe/src/arch/i386/prefix/pciromprefix.S (renamed from roms/ipxe/src/arch/x86/prefix/pciromprefix.S)0
-rw-r--r--roms/ipxe/src/arch/i386/prefix/pxeprefix.S (renamed from roms/ipxe/src/arch/x86/prefix/pxeprefix.S)6
-rw-r--r--roms/ipxe/src/arch/i386/prefix/romprefix.S (renamed from roms/ipxe/src/arch/x86/prefix/romprefix.S)43
-rw-r--r--roms/ipxe/src/arch/i386/prefix/undiloader.S (renamed from roms/ipxe/src/arch/x86/prefix/undiloader.S)23
-rw-r--r--roms/ipxe/src/arch/i386/prefix/unlzma.S (renamed from roms/ipxe/src/arch/x86/prefix/unlzma.S)54
-rw-r--r--roms/ipxe/src/arch/i386/prefix/unlzma16.S (renamed from roms/ipxe/src/arch/x86/prefix/unlzma16.S)0
-rw-r--r--roms/ipxe/src/arch/i386/prefix/usbdisk.S (renamed from roms/ipxe/src/arch/x86/prefix/usbdisk.S)0
-rw-r--r--roms/ipxe/src/arch/i386/scripts/i386.lds (renamed from roms/ipxe/src/arch/x86/scripts/pcbios.lds)30
-rw-r--r--roms/ipxe/src/arch/i386/transitions/liba20.S (renamed from roms/ipxe/src/arch/x86/transitions/liba20.S)0
-rw-r--r--roms/ipxe/src/arch/i386/transitions/libkir.S (renamed from roms/ipxe/src/arch/x86/transitions/libkir.S)0
-rw-r--r--roms/ipxe/src/arch/i386/transitions/libpm.S (renamed from roms/ipxe/src/arch/x86/transitions/libpm.S)0
-rw-r--r--roms/ipxe/src/arch/i386/transitions/librm.S671
-rw-r--r--roms/ipxe/src/arch/i386/transitions/librm_mgmt.c158
-rw-r--r--roms/ipxe/src/arch/i386/transitions/librm_test.c (renamed from roms/ipxe/src/arch/x86/transitions/librm_test.c)40
-rw-r--r--roms/ipxe/src/arch/x86/Makefile16
-rw-r--r--roms/ipxe/src/arch/x86/Makefile.efi42
-rw-r--r--roms/ipxe/src/arch/x86/Makefile.pcbios127
-rw-r--r--roms/ipxe/src/arch/x86/core/gdbmach.c251
-rw-r--r--roms/ipxe/src/arch/x86/core/pcidirect.c6
-rw-r--r--roms/ipxe/src/arch/x86/core/x86_io.c3
-rw-r--r--roms/ipxe/src/arch/x86/core/x86_tcpip.c4
-rw-r--r--roms/ipxe/src/arch/x86/include/bits/bitops.h94
-rw-r--r--roms/ipxe/src/arch/x86/include/bits/errfile.h2
-rw-r--r--roms/ipxe/src/arch/x86/include/bits/iomap.h14
-rw-r--r--roms/ipxe/src/arch/x86/include/bits/tcpip.h6
-rw-r--r--roms/ipxe/src/arch/x86/include/bits/xen.h19
-rw-r--r--roms/ipxe/src/arch/x86/include/ipxe/iomap_pages.h24
-rw-r--r--roms/ipxe/src/arch/x86/include/ipxe/x86_io.h17
-rw-r--r--roms/ipxe/src/arch/x86/include/rmsetjmp.h28
-rw-r--r--roms/ipxe/src/arch/x86/interface/efi/efi_entropy.c (renamed from roms/ipxe/src/interface/efi/efi_entropy.c)8
-rw-r--r--roms/ipxe/src/arch/x86/prefix/efidrvprefix.c (renamed from roms/ipxe/src/interface/efi/efidrvprefix.c)0
-rw-r--r--roms/ipxe/src/arch/x86/prefix/efiprefix.c (renamed from roms/ipxe/src/interface/efi/efiprefix.c)0
-rw-r--r--roms/ipxe/src/arch/x86/scripts/efi.lds (renamed from roms/ipxe/src/scripts/efi.lds)0
-rw-r--r--roms/ipxe/src/arch/x86/transitions/librm.S1592
-rw-r--r--roms/ipxe/src/arch/x86/transitions/librm_mgmt.c310
-rw-r--r--roms/ipxe/src/arch/x86_64/Makefile4
-rw-r--r--roms/ipxe/src/arch/x86_64/Makefile.efi8
-rw-r--r--roms/ipxe/src/arch/x86_64/Makefile.pcbios15
-rw-r--r--roms/ipxe/src/arch/x86_64/core/gdbidt.S168
-rw-r--r--roms/ipxe/src/arch/x86_64/include/bits/compiler.h2
-rw-r--r--roms/ipxe/src/arch/x86_64/include/bits/entropy.h (renamed from roms/ipxe/src/arch/arm/include/bits/entropy.h)2
-rw-r--r--roms/ipxe/src/arch/x86_64/include/bits/hyperv.h23
-rw-r--r--roms/ipxe/src/arch/x86_64/include/bits/nap.h12
-rw-r--r--roms/ipxe/src/arch/x86_64/include/bits/reboot.h (renamed from roms/ipxe/src/arch/arm/include/bits/reboot.h)2
-rw-r--r--roms/ipxe/src/arch/x86_64/include/bits/sanboot.h (renamed from roms/ipxe/src/arch/arm/include/bits/sanboot.h)2
-rw-r--r--roms/ipxe/src/arch/x86_64/include/bits/smbios.h (renamed from roms/ipxe/src/arch/arm/include/bits/smbios.h)4
-rw-r--r--roms/ipxe/src/arch/x86_64/include/bits/time.h (renamed from roms/ipxe/src/arch/arm/include/bits/time.h)2
-rw-r--r--roms/ipxe/src/arch/x86_64/include/bits/timer.h (renamed from roms/ipxe/src/arch/arm/include/bits/timer.h)4
-rw-r--r--roms/ipxe/src/arch/x86_64/include/bits/uaccess.h (renamed from roms/ipxe/src/arch/arm/include/bits/uaccess.h)4
-rw-r--r--roms/ipxe/src/arch/x86_64/include/bits/umalloc.h10
-rw-r--r--roms/ipxe/src/arch/x86_64/include/gdbmach.h49
-rw-r--r--roms/ipxe/src/arch/x86_64/include/pcbios/ipxe/dhcp_arch.h46
-rw-r--r--roms/ipxe/src/config/cloud/aws.ipxe7
-rw-r--r--roms/ipxe/src/config/cloud/colour.h0
-rw-r--r--roms/ipxe/src/config/cloud/console.h31
-rw-r--r--roms/ipxe/src/config/cloud/crypto.h0
-rw-r--r--roms/ipxe/src/config/cloud/general.h0
-rw-r--r--roms/ipxe/src/config/cloud/serial.h0
-rw-r--r--roms/ipxe/src/config/cloud/settings.h0
-rw-r--r--roms/ipxe/src/config/cloud/sideband.h0
-rw-r--r--roms/ipxe/src/config/cloud/usb.h0
-rw-r--r--roms/ipxe/src/config/config.c12
-rw-r--r--roms/ipxe/src/config/config_efi.c51
-rw-r--r--roms/ipxe/src/config/config_ethernet.c3
-rw-r--r--roms/ipxe/src/config/config_infiniband.c17
-rw-r--r--roms/ipxe/src/config/config_linux.c41
-rw-r--r--roms/ipxe/src/config/config_pcbios.c50
-rw-r--r--roms/ipxe/src/config/config_usb.c10
-rw-r--r--roms/ipxe/src/config/console.h46
-rw-r--r--roms/ipxe/src/config/crypto.h8
-rw-r--r--roms/ipxe/src/config/defaults/efi.h20
-rw-r--r--roms/ipxe/src/config/defaults/pcbios.h6
-rw-r--r--roms/ipxe/src/config/dhcp.h6
-rw-r--r--roms/ipxe/src/config/general.h11
-rw-r--r--roms/ipxe/src/config/usb.h15
-rw-r--r--roms/ipxe/src/core/debug.c12
-rw-r--r--roms/ipxe/src/core/downloader.c47
-rw-r--r--roms/ipxe/src/core/exec.c16
-rw-r--r--roms/ipxe/src/core/fbcon.c69
-rw-r--r--roms/ipxe/src/core/gdbstub.c11
-rw-r--r--roms/ipxe/src/core/getkey.c9
-rw-r--r--roms/ipxe/src/core/image.c40
-rw-r--r--roms/ipxe/src/core/iobuf.c43
-rw-r--r--roms/ipxe/src/core/iomap_virt.c36
-rw-r--r--roms/ipxe/src/core/malloc.c108
-rw-r--r--roms/ipxe/src/core/memblock.c85
-rw-r--r--roms/ipxe/src/core/memmap_settings.c2
-rw-r--r--roms/ipxe/src/core/pixbuf.c5
-rw-r--r--roms/ipxe/src/core/random.c2
-rw-r--r--roms/ipxe/src/core/serial.c1
-rw-r--r--roms/ipxe/src/core/settings.c55
-rw-r--r--roms/ipxe/src/core/string.c2
-rw-r--r--roms/ipxe/src/core/time.c3
-rw-r--r--roms/ipxe/src/core/timer.c22
-rw-r--r--roms/ipxe/src/core/uri.c218
-rw-r--r--roms/ipxe/src/core/vsprintf.c6
-rw-r--r--roms/ipxe/src/crypto/asn1.c12
-rw-r--r--roms/ipxe/src/crypto/certstore.c2
-rw-r--r--roms/ipxe/src/crypto/drbg.c12
-rw-r--r--roms/ipxe/src/crypto/hash_df.c12
-rw-r--r--roms/ipxe/src/crypto/hmac.c12
-rw-r--r--roms/ipxe/src/crypto/hmac_drbg.c12
-rw-r--r--roms/ipxe/src/crypto/ocsp.c54
-rw-r--r--roms/ipxe/src/crypto/privkey.c12
-rw-r--r--roms/ipxe/src/crypto/rbg.c12
-rw-r--r--roms/ipxe/src/crypto/rootcert.c10
-rw-r--r--roms/ipxe/src/drivers/block/ibft.c1
-rw-r--r--roms/ipxe/src/drivers/bus/pci.c8
-rw-r--r--roms/ipxe/src/drivers/bus/pci_settings.c2
-rw-r--r--roms/ipxe/src/drivers/bus/pciea.c149
-rw-r--r--roms/ipxe/src/drivers/bus/pciextra.c54
-rw-r--r--roms/ipxe/src/drivers/bus/usb.c527
-rw-r--r--roms/ipxe/src/drivers/bus/virtio-pci.c353
-rw-r--r--roms/ipxe/src/drivers/bus/virtio-ring.c17
-rwxr-xr-xroms/ipxe/src/drivers/infiniband/CIB_PRM.h1168
-rw-r--r--roms/ipxe/src/drivers/infiniband/arbel.c94
-rw-r--r--roms/ipxe/src/drivers/infiniband/arbel.h6
-rw-r--r--roms/ipxe/src/drivers/infiniband/flexboot_nodnic.c1479
-rw-r--r--roms/ipxe/src/drivers/infiniband/flexboot_nodnic.h163
-rwxr-xr-xroms/ipxe/src/drivers/infiniband/golan.c2672
-rwxr-xr-xroms/ipxe/src/drivers/infiniband/golan.h326
-rw-r--r--roms/ipxe/src/drivers/infiniband/hermon.c102
-rw-r--r--roms/ipxe/src/drivers/infiniband/hermon.h6
-rw-r--r--roms/ipxe/src/drivers/infiniband/linda.c51
-rw-r--r--roms/ipxe/src/drivers/infiniband/linda.h4
-rw-r--r--roms/ipxe/src/drivers/infiniband/mlx_nodnic/include/mlx_cmd.h43
-rw-r--r--roms/ipxe/src/drivers/infiniband/mlx_nodnic/include/mlx_device.h80
-rw-r--r--roms/ipxe/src/drivers/infiniband/mlx_nodnic/include/mlx_nodnic_data_structures.h201
-rw-r--r--roms/ipxe/src/drivers/infiniband/mlx_nodnic/include/mlx_port.h229
-rw-r--r--roms/ipxe/src/drivers/infiniband/mlx_nodnic/src/mlx_cmd.c77
-rw-r--r--roms/ipxe/src/drivers/infiniband/mlx_nodnic/src/mlx_device.c339
-rw-r--r--roms/ipxe/src/drivers/infiniband/mlx_nodnic/src/mlx_port.c1038
-rw-r--r--roms/ipxe/src/drivers/infiniband/mlx_utils/include/private/mlx_memory_priv.h113
-rw-r--r--roms/ipxe/src/drivers/infiniband/mlx_utils/include/private/mlx_pci_priv.h72
-rw-r--r--roms/ipxe/src/drivers/infiniband/mlx_utils/include/private/mlx_utils_priv.h68
-rw-r--r--roms/ipxe/src/drivers/infiniband/mlx_utils/include/public/mlx_bail.h47
-rw-r--r--roms/ipxe/src/drivers/infiniband/mlx_utils/include/public/mlx_icmd.h63
-rw-r--r--roms/ipxe/src/drivers/infiniband/mlx_utils/include/public/mlx_logging.h46
-rw-r--r--roms/ipxe/src/drivers/infiniband/mlx_utils/include/public/mlx_memory.h115
-rw-r--r--roms/ipxe/src/drivers/infiniband/mlx_utils/include/public/mlx_pci.h78
-rw-r--r--roms/ipxe/src/drivers/infiniband/mlx_utils/include/public/mlx_pci_gw.h81
-rw-r--r--roms/ipxe/src/drivers/infiniband/mlx_utils/include/public/mlx_types.h27
-rw-r--r--roms/ipxe/src/drivers/infiniband/mlx_utils/include/public/mlx_utils.h106
-rw-r--r--roms/ipxe/src/drivers/infiniband/mlx_utils/mlx_lib/mlx_blink_leds/mlx_blink_leds.c54
-rw-r--r--roms/ipxe/src/drivers/infiniband/mlx_utils/mlx_lib/mlx_blink_leds/mlx_blink_leds.h46
-rw-r--r--roms/ipxe/src/drivers/infiniband/mlx_utils/mlx_lib/mlx_link_speed/mlx_link_speed.c180
-rw-r--r--roms/ipxe/src/drivers/infiniband/mlx_utils/mlx_lib/mlx_link_speed/mlx_link_speed.h145
-rw-r--r--roms/ipxe/src/drivers/infiniband/mlx_utils/mlx_lib/mlx_mtu/mlx_mtu.c60
-rw-r--r--roms/ipxe/src/drivers/infiniband/mlx_utils/mlx_lib/mlx_mtu/mlx_mtu.h52
-rw-r--r--roms/ipxe/src/drivers/infiniband/mlx_utils/mlx_lib/mlx_nvconfig/mlx_nvconfig.c295
-rw-r--r--roms/ipxe/src/drivers/infiniband/mlx_utils/mlx_lib/mlx_nvconfig/mlx_nvconfig.h140
-rw-r--r--roms/ipxe/src/drivers/infiniband/mlx_utils/mlx_lib/mlx_nvconfig/mlx_nvconfig_defaults.c482
-rw-r--r--roms/ipxe/src/drivers/infiniband/mlx_utils/mlx_lib/mlx_nvconfig/mlx_nvconfig_defaults.h94
-rw-r--r--roms/ipxe/src/drivers/infiniband/mlx_utils/mlx_lib/mlx_nvconfig/mlx_nvconfig_prm.h259
-rw-r--r--roms/ipxe/src/drivers/infiniband/mlx_utils/mlx_lib/mlx_ocbb/mlx_ocbb.c145
-rw-r--r--roms/ipxe/src/drivers/infiniband/mlx_utils/mlx_lib/mlx_ocbb/mlx_ocbb.h73
-rw-r--r--roms/ipxe/src/drivers/infiniband/mlx_utils/mlx_lib/mlx_reg_access/mlx_reg_access.c90
-rw-r--r--roms/ipxe/src/drivers/infiniband/mlx_utils/mlx_lib/mlx_reg_access/mlx_reg_access.h82
-rw-r--r--roms/ipxe/src/drivers/infiniband/mlx_utils/mlx_lib/mlx_vmac/mlx_vmac.c74
-rw-r--r--roms/ipxe/src/drivers/infiniband/mlx_utils/mlx_lib/mlx_vmac/mlx_vmac.h60
-rw-r--r--roms/ipxe/src/drivers/infiniband/mlx_utils/mlx_lib/mlx_wol_rol/mlx_wol_rol.c84
-rw-r--r--roms/ipxe/src/drivers/infiniband/mlx_utils/mlx_lib/mlx_wol_rol/mlx_wol_rol.h61
-rw-r--r--roms/ipxe/src/drivers/infiniband/mlx_utils/src/private/uefi/mlx_logging_impl.c9
-rw-r--r--roms/ipxe/src/drivers/infiniband/mlx_utils/src/public/mlx_icmd.c371
-rw-r--r--roms/ipxe/src/drivers/infiniband/mlx_utils/src/public/mlx_memory.c238
-rw-r--r--roms/ipxe/src/drivers/infiniband/mlx_utils/src/public/mlx_pci.c117
-rw-r--r--roms/ipxe/src/drivers/infiniband/mlx_utils/src/public/mlx_pci_gw.c392
-rw-r--r--roms/ipxe/src/drivers/infiniband/mlx_utils/src/public/mlx_utils.c121
-rw-r--r--roms/ipxe/src/drivers/infiniband/mlx_utils_flexboot/include/mlx_logging_priv.h61
-rw-r--r--roms/ipxe/src/drivers/infiniband/mlx_utils_flexboot/include/mlx_types_priv.h60
-rw-r--r--roms/ipxe/src/drivers/infiniband/mlx_utils_flexboot/src/mlx_memory_priv.c172
-rw-r--r--roms/ipxe/src/drivers/infiniband/mlx_utils_flexboot/src/mlx_pci_priv.c182
-rw-r--r--roms/ipxe/src/drivers/infiniband/mlx_utils_flexboot/src/mlx_utils_priv.c83
-rw-r--r--roms/ipxe/src/drivers/infiniband/nodnic_prm.h47
-rw-r--r--roms/ipxe/src/drivers/infiniband/nodnic_shomron_prm.h143
-rw-r--r--roms/ipxe/src/drivers/infiniband/qib7322.c51
-rw-r--r--roms/ipxe/src/drivers/infiniband/qib7322.h4
-rw-r--r--roms/ipxe/src/drivers/net/3c595.c2
-rw-r--r--roms/ipxe/src/drivers/net/3c5x9.c2
-rw-r--r--roms/ipxe/src/drivers/net/acm.c529
-rw-r--r--roms/ipxe/src/drivers/net/acm.h69
-rw-r--r--roms/ipxe/src/drivers/net/ath/ath.h6
-rw-r--r--roms/ipxe/src/drivers/net/ath/ath5k/ath5k.c40
-rw-r--r--roms/ipxe/src/drivers/net/ath/ath5k/ath5k_phy.c6
-rw-r--r--roms/ipxe/src/drivers/net/ath/ath5k/ath5k_reset.c8
-rw-r--r--roms/ipxe/src/drivers/net/ath/ath9k/ar9002_initvals.h72
-rw-r--r--roms/ipxe/src/drivers/net/ath/ath9k/ar9003_2p2_initvals.h40
-rw-r--r--roms/ipxe/src/drivers/net/ath/ath9k/ar9340_initvals.h36
-rw-r--r--roms/ipxe/src/drivers/net/ath/ath9k/ar9485_initvals.h44
-rw-r--r--roms/ipxe/src/drivers/net/ath/ath9k/ath9k_eeprom.c7
-rw-r--r--roms/ipxe/src/drivers/net/ath/ath9k/ath9k_init.c3
-rw-r--r--roms/ipxe/src/drivers/net/ath/ath9k/ath9k_recv.c12
-rw-r--r--roms/ipxe/src/drivers/net/ath/ath_main.c59
-rw-r--r--roms/ipxe/src/drivers/net/axge.c798
-rw-r--r--roms/ipxe/src/drivers/net/axge.h174
-rw-r--r--roms/ipxe/src/drivers/net/dm96xx.c6
-rw-r--r--roms/ipxe/src/drivers/net/ecm.c11
-rw-r--r--roms/ipxe/src/drivers/net/efi/nii.c4
-rw-r--r--roms/ipxe/src/drivers/net/efi/snp.c24
-rw-r--r--roms/ipxe/src/drivers/net/efi/snpnet.c25
-rw-r--r--roms/ipxe/src/drivers/net/efi/snponly.c32
-rw-r--r--roms/ipxe/src/drivers/net/eoib.c895
-rw-r--r--roms/ipxe/src/drivers/net/etherfabric.c2
-rw-r--r--roms/ipxe/src/drivers/net/intel.c35
-rw-r--r--roms/ipxe/src/drivers/net/intel.h4
-rw-r--r--roms/ipxe/src/drivers/net/ipoib.c191
-rw-r--r--roms/ipxe/src/drivers/net/ncm.c20
-rw-r--r--roms/ipxe/src/drivers/net/ncm.h5
-rw-r--r--roms/ipxe/src/drivers/net/phantom/phantom.c12
-rw-r--r--roms/ipxe/src/drivers/net/sis190.c6
-rw-r--r--roms/ipxe/src/drivers/net/sis190.h7
-rwxr-xr-xroms/ipxe/src/drivers/net/skge.c5
-rw-r--r--roms/ipxe/src/drivers/net/smsc75xx.c32
-rw-r--r--roms/ipxe/src/drivers/net/smsc75xx.h4
-rw-r--r--roms/ipxe/src/drivers/net/smsc95xx.c1300
-rw-r--r--roms/ipxe/src/drivers/net/smsc95xx.h269
-rw-r--r--roms/ipxe/src/drivers/net/tg3/tg3.c4
-rw-r--r--roms/ipxe/src/drivers/net/tg3/tg3.h39
-rw-r--r--roms/ipxe/src/drivers/net/thunderx.c1706
-rw-r--r--roms/ipxe/src/drivers/net/thunderx.h949
-rw-r--r--roms/ipxe/src/drivers/net/thunderxcfg.h211
-rw-r--r--roms/ipxe/src/drivers/net/virtio-net.c265
-rw-r--r--roms/ipxe/src/drivers/net/virtio-net.h16
-rw-r--r--roms/ipxe/src/drivers/net/vmxnet3.c13
-rw-r--r--roms/ipxe/src/drivers/net/vmxnet3.h3
-rw-r--r--roms/ipxe/src/drivers/usb/ehci.c148
-rw-r--r--roms/ipxe/src/drivers/usb/uhci.c8
-rw-r--r--roms/ipxe/src/drivers/usb/usbhub.c31
-rw-r--r--roms/ipxe/src/drivers/usb/usbhub.h8
-rw-r--r--roms/ipxe/src/drivers/usb/usbio.c1717
-rw-r--r--roms/ipxe/src/drivers/usb/usbio.h153
-rw-r--r--roms/ipxe/src/drivers/usb/usbkbd.c98
-rw-r--r--roms/ipxe/src/drivers/usb/usbkbd.h19
-rw-r--r--roms/ipxe/src/drivers/usb/usbnet.c4
-rw-r--r--roms/ipxe/src/drivers/usb/xhci.c69
-rw-r--r--roms/ipxe/src/hci/commands/ibmgmt_cmd.c79
-rw-r--r--roms/ipxe/src/hci/commands/lotest_cmd.c7
-rw-r--r--roms/ipxe/src/hci/commands/ntp_cmd.c81
-rw-r--r--roms/ipxe/src/hci/mucurses/windows.c11
-rw-r--r--roms/ipxe/src/image/efi_image.c17
-rw-r--r--roms/ipxe/src/image/embedded.c2
-rw-r--r--roms/ipxe/src/include/compiler.h17
-rw-r--r--roms/ipxe/src/include/errno.h2
-rw-r--r--roms/ipxe/src/include/ipxe/asn1.h16
-rw-r--r--roms/ipxe/src/include/ipxe/bitops.h230
-rw-r--r--roms/ipxe/src/include/ipxe/cdc.h49
-rw-r--r--roms/ipxe/src/include/ipxe/dhcp.h18
-rw-r--r--roms/ipxe/src/include/ipxe/efi/AArch64/ProcessorBind.h150
-rw-r--r--roms/ipxe/src/include/ipxe/efi/Arm/ProcessorBind.h171
-rw-r--r--roms/ipxe/src/include/ipxe/efi/Base.h60
-rw-r--r--roms/ipxe/src/include/ipxe/efi/Guid/SmBios.h14
-rw-r--r--roms/ipxe/src/include/ipxe/efi/Ia32/ProcessorBind.h22
-rw-r--r--roms/ipxe/src/include/ipxe/efi/IndustryStandard/Acpi20.h547
-rw-r--r--roms/ipxe/src/include/ipxe/efi/IndustryStandard/Acpi30.h731
-rw-r--r--roms/ipxe/src/include/ipxe/efi/IndustryStandard/Acpi40.h1311
-rw-r--r--roms/ipxe/src/include/ipxe/efi/IndustryStandard/Acpi50.h2121
-rw-r--r--roms/ipxe/src/include/ipxe/efi/IndustryStandard/Acpi51.h2141
-rw-r--r--roms/ipxe/src/include/ipxe/efi/IndustryStandard/Acpi60.h2348
-rw-r--r--roms/ipxe/src/include/ipxe/efi/IndustryStandard/Bluetooth.h49
-rw-r--r--roms/ipxe/src/include/ipxe/efi/IndustryStandard/Pci22.h3
-rw-r--r--roms/ipxe/src/include/ipxe/efi/IndustryStandard/Tpm20.h1822
-rw-r--r--roms/ipxe/src/include/ipxe/efi/IndustryStandard/UefiTcgPlatform.h110
-rw-r--r--roms/ipxe/src/include/ipxe/efi/IndustryStandard/Usb.h388
-rw-r--r--roms/ipxe/src/include/ipxe/efi/Library/BaseLib.h433
-rw-r--r--roms/ipxe/src/include/ipxe/efi/Pi/PiDxeCis.h62
-rw-r--r--roms/ipxe/src/include/ipxe/efi/Pi/PiFirmwareFile.h8
-rw-r--r--roms/ipxe/src/include/ipxe/efi/Pi/PiHob.h31
-rw-r--r--roms/ipxe/src/include/ipxe/efi/Pi/PiMultiPhase.h16
-rw-r--r--roms/ipxe/src/include/ipxe/efi/ProcessorBind.h8
-rw-r--r--roms/ipxe/src/include/ipxe/efi/Protocol/AbsolutePointer.h207
-rw-r--r--roms/ipxe/src/include/ipxe/efi/Protocol/AppleNetBoot.h46
-rw-r--r--roms/ipxe/src/include/ipxe/efi/Protocol/Cpu.h302
-rw-r--r--roms/ipxe/src/include/ipxe/efi/Protocol/DevicePath.h173
-rw-r--r--roms/ipxe/src/include/ipxe/efi/Protocol/FormBrowser2.h3
-rw-r--r--roms/ipxe/src/include/ipxe/efi/Protocol/HiiConfigAccess.h3
-rw-r--r--roms/ipxe/src/include/ipxe/efi/Protocol/HiiFont.h474
-rw-r--r--roms/ipxe/src/include/ipxe/efi/Protocol/HiiImage.h356
-rw-r--r--roms/ipxe/src/include/ipxe/efi/Protocol/LoadFile.h4
-rw-r--r--roms/ipxe/src/include/ipxe/efi/Protocol/SerialIo.h301
-rw-r--r--roms/ipxe/src/include/ipxe/efi/Protocol/SimpleNetwork.h21
-rw-r--r--roms/ipxe/src/include/ipxe/efi/Protocol/SimplePointer.h145
-rw-r--r--roms/ipxe/src/include/ipxe/efi/Protocol/SimpleTextOut.h17
-rw-r--r--roms/ipxe/src/include/ipxe/efi/Protocol/TcgService.h10
-rw-r--r--roms/ipxe/src/include/ipxe/efi/Protocol/UgaDraw.h168
-rw-r--r--roms/ipxe/src/include/ipxe/efi/Protocol/UnicodeCollation.h194
-rw-r--r--roms/ipxe/src/include/ipxe/efi/Protocol/Usb2HostController.h666
-rw-r--r--roms/ipxe/src/include/ipxe/efi/Protocol/UsbHostController.h510
-rw-r--r--roms/ipxe/src/include/ipxe/efi/Protocol/UsbIo.h514
-rw-r--r--roms/ipxe/src/include/ipxe/efi/Uefi/UefiBaseType.h6
-rw-r--r--roms/ipxe/src/include/ipxe/efi/Uefi/UefiInternalFormRepresentation.h17
-rw-r--r--roms/ipxe/src/include/ipxe/efi/Uefi/UefiMultiPhase.h40
-rw-r--r--roms/ipxe/src/include/ipxe/efi/Uefi/UefiPxe.h22
-rw-r--r--roms/ipxe/src/include/ipxe/efi/Uefi/UefiSpec.h646
-rw-r--r--roms/ipxe/src/include/ipxe/efi/X64/ProcessorBind.h26
-rw-r--r--roms/ipxe/src/include/ipxe/efi/efi.h30
-rw-r--r--roms/ipxe/src/include/ipxe/efi/efi_driver.h2
-rw-r--r--roms/ipxe/src/include/ipxe/efi/efi_pxe.h17
-rw-r--r--roms/ipxe/src/include/ipxe/efi/efi_snp.h6
-rw-r--r--roms/ipxe/src/include/ipxe/efi/efi_timer.h18
-rw-r--r--roms/ipxe/src/include/ipxe/efi/efi_usb.h80
-rw-r--r--roms/ipxe/src/include/ipxe/efi/efi_utils.h1
-rw-r--r--roms/ipxe/src/include/ipxe/eoib.h103
-rw-r--r--roms/ipxe/src/include/ipxe/errfile.h17
-rw-r--r--roms/ipxe/src/include/ipxe/fbcon.h26
-rw-r--r--roms/ipxe/src/include/ipxe/ib_cmrc.h7
-rw-r--r--roms/ipxe/src/include/ipxe/ib_mad.h31
-rw-r--r--roms/ipxe/src/include/ipxe/ib_mcast.h21
-rw-r--r--roms/ipxe/src/include/ipxe/ib_packet.h5
-rw-r--r--roms/ipxe/src/include/ipxe/ib_service.h20
-rw-r--r--roms/ipxe/src/include/ipxe/if_arp.h10
-rw-r--r--roms/ipxe/src/include/ipxe/image.h1
-rw-r--r--roms/ipxe/src/include/ipxe/infiniband.h39
-rw-r--r--roms/ipxe/src/include/ipxe/io.h26
-rw-r--r--roms/ipxe/src/include/ipxe/iomap.h78
-rw-r--r--roms/ipxe/src/include/ipxe/iomap_virt.h33
-rw-r--r--roms/ipxe/src/include/ipxe/ipoib.h1
-rw-r--r--roms/ipxe/src/include/ipxe/linux_compat.h27
-rw-r--r--roms/ipxe/src/include/ipxe/ntp.h109
-rw-r--r--roms/ipxe/src/include/ipxe/pci.h26
-rw-r--r--roms/ipxe/src/include/ipxe/pciea.h70
-rw-r--r--roms/ipxe/src/include/ipxe/pool.h2
-rw-r--r--roms/ipxe/src/include/ipxe/pseudobit.h249
-rw-r--r--roms/ipxe/src/include/ipxe/sanboot.h2
-rw-r--r--roms/ipxe/src/include/ipxe/settings.h14
-rw-r--r--roms/ipxe/src/include/ipxe/smbios.h3
-rw-r--r--roms/ipxe/src/include/ipxe/tcp.h10
-rw-r--r--roms/ipxe/src/include/ipxe/tcpip.h54
-rw-r--r--roms/ipxe/src/include/ipxe/time.h15
-rw-r--r--roms/ipxe/src/include/ipxe/uri.h9
-rw-r--r--roms/ipxe/src/include/ipxe/usb.h114
-rw-r--r--roms/ipxe/src/include/ipxe/usbhid.h34
-rw-r--r--roms/ipxe/src/include/ipxe/virtio-pci.h207
-rw-r--r--roms/ipxe/src/include/ipxe/virtio-ring.h14
-rw-r--r--roms/ipxe/src/include/ipxe/xen.h14
-rw-r--r--roms/ipxe/src/include/ipxe/xsigo.h406
-rw-r--r--roms/ipxe/src/include/nic.h3
-rw-r--r--roms/ipxe/src/include/stddef.h2
-rw-r--r--roms/ipxe/src/include/string.h14
-rw-r--r--roms/ipxe/src/include/time.h4
-rw-r--r--roms/ipxe/src/include/usr/ibmgmt.h16
-rw-r--r--roms/ipxe/src/include/usr/lotest.h3
-rw-r--r--roms/ipxe/src/include/usr/ntpmgmt.h14
-rw-r--r--roms/ipxe/src/interface/bofm/bofm.c4
-rw-r--r--roms/ipxe/src/interface/efi/efi_bofm.c67
-rw-r--r--roms/ipxe/src/interface/efi/efi_console.c8
-rw-r--r--roms/ipxe/src/interface/efi/efi_debug.c164
-rw-r--r--roms/ipxe/src/interface/efi/efi_driver.c135
-rw-r--r--roms/ipxe/src/interface/efi/efi_fbcon.c573
-rw-r--r--roms/ipxe/src/interface/efi/efi_file.c9
-rw-r--r--roms/ipxe/src/interface/efi/efi_guid.c87
-rw-r--r--roms/ipxe/src/interface/efi/efi_local.c573
-rw-r--r--roms/ipxe/src/interface/efi/efi_pci.c178
-rw-r--r--roms/ipxe/src/interface/efi/efi_pxe.c1687
-rw-r--r--roms/ipxe/src/interface/efi/efi_snp.c786
-rw-r--r--roms/ipxe/src/interface/efi/efi_snp_hii.c7
-rw-r--r--roms/ipxe/src/interface/efi/efi_timer.c130
-rw-r--r--roms/ipxe/src/interface/efi/efi_usb.c1305
-rw-r--r--roms/ipxe/src/interface/efi/efi_utils.c50
-rw-r--r--roms/ipxe/src/interface/efi/efi_wrap.c371
-rw-r--r--roms/ipxe/src/interface/hyperv/vmbus.c5
-rw-r--r--roms/ipxe/src/interface/smbios/smbios_settings.c2
-rw-r--r--roms/ipxe/src/libgcc/__divdi3.c18
-rw-r--r--roms/ipxe/src/libgcc/__divmoddi4.c25
-rw-r--r--roms/ipxe/src/libgcc/__moddi3.c15
-rw-r--r--roms/ipxe/src/libgcc/implicit.c26
-rw-r--r--roms/ipxe/src/libgcc/libgcc.h1
-rw-r--r--roms/ipxe/src/libgcc/memcpy.c18
-rw-r--r--roms/ipxe/src/net/arp.c7
-rw-r--r--roms/ipxe/src/net/ethernet.c3
-rw-r--r--roms/ipxe/src/net/fakedhcp.c4
-rw-r--r--roms/ipxe/src/net/infiniband.c167
-rw-r--r--roms/ipxe/src/net/infiniband/ib_cm.c70
-rw-r--r--roms/ipxe/src/net/infiniband/ib_cmrc.c87
-rw-r--r--roms/ipxe/src/net/infiniband/ib_mcast.c112
-rw-r--r--roms/ipxe/src/net/infiniband/ib_mi.c32
-rw-r--r--roms/ipxe/src/net/infiniband/ib_packet.c45
-rw-r--r--roms/ipxe/src/net/infiniband/ib_pathrec.c34
-rw-r--r--roms/ipxe/src/net/infiniband/ib_service.c67
-rw-r--r--roms/ipxe/src/net/infiniband/ib_sma.c8
-rw-r--r--roms/ipxe/src/net/infiniband/ib_smc.c20
-rw-r--r--roms/ipxe/src/net/infiniband/ib_srp.c2
-rw-r--r--roms/ipxe/src/net/infiniband/xsigo.c1858
-rw-r--r--roms/ipxe/src/net/ipv4.c6
-rw-r--r--roms/ipxe/src/net/ipv6.c3
-rw-r--r--roms/ipxe/src/net/netdev_settings.c25
-rw-r--r--roms/ipxe/src/net/netdevice.c10
-rw-r--r--roms/ipxe/src/net/peerblk.c17
-rw-r--r--roms/ipxe/src/net/stp.c6
-rw-r--r--roms/ipxe/src/net/tcp.c102
-rw-r--r--roms/ipxe/src/net/tcp/httpconn.c19
-rw-r--r--roms/ipxe/src/net/tcp/httpcore.c89
-rw-r--r--roms/ipxe/src/net/tcpip.c15
-rw-r--r--roms/ipxe/src/net/tls.c111
-rw-r--r--roms/ipxe/src/net/udp.c1
-rw-r--r--roms/ipxe/src/net/udp/dhcp.c14
-rw-r--r--roms/ipxe/src/net/udp/ntp.c275
-rw-r--r--roms/ipxe/src/net/udp/slam.c20
-rw-r--r--roms/ipxe/src/net/udp/tftp.c30
-rw-r--r--roms/ipxe/src/net/validator.c3
-rw-r--r--roms/ipxe/src/tests/bitops_test.c102
-rw-r--r--roms/ipxe/src/tests/comboot/shuffle-simple.asm (renamed from roms/ipxe/src/arch/x86/tests/comboot/shuffle-simple.asm)3
-rw-r--r--roms/ipxe/src/tests/comboot/version.asm (renamed from roms/ipxe/src/arch/x86/tests/comboot/version.asm)0
-rw-r--r--roms/ipxe/src/tests/gdbstub_test.S (renamed from roms/ipxe/src/arch/i386/tests/gdbstub_test.S)0
-rwxr-xr-xroms/ipxe/src/tests/gdbstub_test.gdb (renamed from roms/ipxe/src/arch/i386/tests/gdbstub_test.gdb)0
-rw-r--r--roms/ipxe/src/tests/iobuf_test.c136
-rw-r--r--roms/ipxe/src/tests/rsa_test.c1
-rw-r--r--roms/ipxe/src/tests/settings_test.c20
-rw-r--r--roms/ipxe/src/tests/tcpip_test.c19
-rw-r--r--roms/ipxe/src/tests/tests.c2
-rw-r--r--roms/ipxe/src/tests/uri_test.c163
-rw-r--r--roms/ipxe/src/tests/vsprintf_test.c43
-rw-r--r--roms/ipxe/src/usr/autoboot.c99
-rw-r--r--roms/ipxe/src/usr/ibmgmt.c62
-rw-r--r--roms/ipxe/src/usr/ifmgmt.c6
-rw-r--r--roms/ipxe/src/usr/lotest.c14
-rw-r--r--roms/ipxe/src/usr/ntpmgmt.c57
-rw-r--r--roms/ipxe/src/util/efifatbin.c3
-rw-r--r--roms/ipxe/src/util/efirom.c5
-rw-r--r--roms/ipxe/src/util/elf2efi.c553
-rwxr-xr-xroms/ipxe/src/util/genefidsk60
-rwxr-xr-xroms/ipxe/src/util/geniso3
-rwxr-xr-xroms/ipxe/src/util/parserom.pl2
-rw-r--r--roms/ipxe/src/util/zbin.c52
-rw-r--r--roms/openbios/arch/amd64/context.c5
-rw-r--r--roms/openbios/arch/ppc/build.xml2
-rw-r--r--roms/openbios/arch/ppc/qemu/context.c140
-rw-r--r--roms/openbios/arch/ppc/qemu/context.h34
-rw-r--r--roms/openbios/arch/ppc/qemu/init.c4
-rw-r--r--roms/openbios/arch/ppc/qemu/ldscript6
-rw-r--r--roms/openbios/arch/ppc/qemu/ofmem.c48
-rw-r--r--roms/openbios/arch/ppc/qemu/start.S244
-rw-r--r--roms/openbios/arch/ppc/qemu/switch.S211
-rw-r--r--roms/openbios/arch/sparc32/openbios.c2
-rw-r--r--roms/openbios/arch/sparc64/context.c5
-rw-r--r--roms/openbios/forth/bootstrap/interpreter.fs4
-rw-r--r--roms/openbios/forth/lib/build.xml1
-rw-r--r--roms/openbios/forth/lib/rstack.fs21
-rw-r--r--roms/openbios/include/arch/ppc/io.h2
-rw-r--r--roms/seabios/.version2
-rwxr-xr-xroms/seabios/scripts/layoutrom.py14
-rw-r--r--roms/seabios/src/fw/paravirt.c12
-rw-r--r--roms/seabios/src/fw/pciinit.c121
-rw-r--r--roms/seabios/src/fw/smp.c20
-rw-r--r--rules.mak15
-rw-r--r--scripts/analyze-inclusions102
-rwxr-xr-xscripts/checkpatch.pl127
-rwxr-xr-xscripts/clean-header-guards.pl213
-rwxr-xr-xscripts/clean-includes8
-rw-r--r--scripts/cocci-macro-file.h6
-rw-r--r--scripts/coccinelle/err-bad-newline.cocci29
-rw-r--r--scripts/coccinelle/error_propagate_null.cocci10
-rw-r--r--scripts/coccinelle/overflow_muldiv64.cocci16
-rw-r--r--scripts/coccinelle/remove_local_err.cocci29
-rw-r--r--scripts/coccinelle/remove_muldiv64.cocci6
-rw-r--r--scripts/coccinelle/return_directly.cocci19
-rw-r--r--scripts/coccinelle/round.cocci19
-rw-r--r--scripts/coccinelle/simplify_muldiv64.cocci11
-rw-r--r--scripts/coccinelle/swap_muldiv64.cocci13
-rwxr-xr-xscripts/create_config12
-rw-r--r--scripts/dump-guest-memory.py83
-rw-r--r--scripts/feature_to_c.sh8
-rwxr-xr-xscripts/kvm/kvm_stat827
-rw-r--r--scripts/kvm/kvm_stat.texi55
-rw-r--r--scripts/make_device_config.sh4
-rw-r--r--scripts/qapi-commands.py70
-rw-r--r--scripts/qapi-event.py63
-rw-r--r--scripts/qapi-introspect.py4
-rw-r--r--scripts/qapi-types.py8
-rw-r--r--scripts/qapi-visit.py65
-rw-r--r--scripts/qapi.py127
-rw-r--r--[-rwxr-xr-x]scripts/qemu-binfmt-conf.sh389
-rw-r--r--scripts/qemu.py222
-rw-r--r--scripts/qmp/__init__.py0
-rw-r--r--scripts/qmp/qmp.py15
-rw-r--r--scripts/qtest.py39
-rw-r--r--scripts/signrom.py23
-rw-r--r--scripts/tracetool/backend/dtrace.py4
-rw-r--r--scripts/tracetool/backend/ftrace.py20
-rw-r--r--scripts/tracetool/backend/log.py26
-rw-r--r--scripts/tracetool/backend/simple.py13
-rw-r--r--scripts/tracetool/backend/ust.py4
-rw-r--r--scripts/tracetool/format/events_c.py11
-rw-r--r--scripts/tracetool/format/events_h.py12
-rw-r--r--scripts/tracetool/format/h.py19
-rw-r--r--scripts/tracetool/format/tcg_helper_c.py1
-rwxr-xr-xscripts/update-linux-headers.sh2
-rwxr-xr-xscripts/vmstate-static-checker.py2
-rw-r--r--slirp/Makefile.objs2
-rw-r--r--slirp/bootp.c2
-rw-r--r--slirp/bootp.h3
-rw-r--r--slirp/cksum.c2
-rw-r--r--slirp/dhcpv6.c209
-rw-r--r--slirp/dhcpv6.h22
-rw-r--r--slirp/dnssearch.c5
-rw-r--r--slirp/if.c2
-rw-r--r--slirp/if.h4
-rw-r--r--slirp/ip.h4
-rw-r--r--slirp/ip6.h13
-rw-r--r--slirp/ip6_icmp.c28
-rw-r--r--slirp/ip6_icmp.h16
-rw-r--r--slirp/ip_icmp.h4
-rw-r--r--slirp/ip_input.c3
-rw-r--r--slirp/ip_output.c2
-rw-r--r--slirp/libslirp.h5
-rw-r--r--slirp/main.h3
-rw-r--r--slirp/mbuf.c2
-rw-r--r--slirp/mbuf.h4
-rw-r--r--slirp/misc.c26
-rw-r--r--slirp/misc.h4
-rw-r--r--slirp/sbuf.c4
-rw-r--r--slirp/sbuf.h4
-rw-r--r--slirp/slirp.c144
-rw-r--r--slirp/slirp.h60
-rw-r--r--slirp/slirp_config.h99
-rw-r--r--slirp/socket.c9
-rw-r--r--slirp/socket.h6
-rw-r--r--slirp/tcp.h4
-rw-r--r--slirp/tcp_input.c2
-rw-r--r--slirp/tcp_output.c2
-rw-r--r--slirp/tcp_subr.c2
-rw-r--r--slirp/tcp_timer.c2
-rw-r--r--slirp/tcp_timer.h4
-rw-r--r--slirp/tcp_var.h4
-rw-r--r--slirp/tcpip.h4
-rw-r--r--slirp/tftp.c6
-rw-r--r--slirp/tftp.h3
-rw-r--r--slirp/udp.c2
-rw-r--r--slirp/udp.h4
-rw-r--r--slirp/udp6.c14
-rw-r--r--softmmu_template.h163
-rw-r--r--stubs/Makefile.objs4
-rw-r--r--stubs/cpu-get-icount.c1
-rw-r--r--stubs/ipmi.c14
-rw-r--r--stubs/pc_madt_cpu_entry.c7
-rw-r--r--stubs/slirp.c1
-rw-r--r--stubs/smbios_type_38.c14
-rw-r--r--stubs/trace-control.c28
-rw-r--r--target-alpha/cpu-qom.h41
-rw-r--r--target-alpha/cpu.c1
-rw-r--r--target-alpha/cpu.h55
-rw-r--r--target-alpha/fpu_helper.c1
-rw-r--r--target-alpha/gdbstub.c1
-rw-r--r--target-alpha/helper.c1
-rw-r--r--target-alpha/int_helper.c1
-rw-r--r--target-alpha/machine.c3
-rw-r--r--target-alpha/mem_helper.c8
-rw-r--r--target-alpha/sys_helper.c1
-rw-r--r--target-alpha/translate.c18
-rw-r--r--target-alpha/vax_helper.c1
-rw-r--r--target-arm/Makefile.objs1
-rw-r--r--target-arm/arm-powerctl.c226
-rw-r--r--target-arm/arm-powerctl.h75
-rw-r--r--target-arm/arm-semi.c49
-rw-r--r--target-arm/arm_ldst.h1
-rw-r--r--target-arm/cpu-qom.h178
-rw-r--r--target-arm/cpu.c11
-rw-r--r--target-arm/cpu.h255
-rw-r--r--target-arm/gdbstub.c1
-rw-r--r--target-arm/gdbstub64.c1
-rw-r--r--target-arm/helper-a64.c15
-rw-r--r--target-arm/helper.c291
-rw-r--r--target-arm/internals.h58
-rw-r--r--target-arm/kvm-stub.c1
-rw-r--r--target-arm/kvm.c13
-rw-r--r--target-arm/kvm32.c10
-rw-r--r--target-arm/kvm64.c49
-rw-r--r--target-arm/kvm_arm.h7
-rw-r--r--target-arm/machine.c9
-rw-r--r--target-arm/monitor.c3
-rw-r--r--target-arm/neon_helper.c2
-rw-r--r--target-arm/op_helper.c72
-rw-r--r--target-arm/psci.c80
-rw-r--r--target-arm/translate-a64.c188
-rw-r--r--target-arm/translate.c52
-rw-r--r--target-arm/translate.h2
-rw-r--r--target-cris/cpu-qom.h40
-rw-r--r--target-cris/cpu.c1
-rw-r--r--target-cris/cpu.h52
-rw-r--r--target-cris/crisv32-decode.h3
-rw-r--r--target-cris/gdbstub.c1
-rw-r--r--target-cris/helper.c1
-rw-r--r--target-cris/machine.c3
-rw-r--r--target-cris/mmu.c1
-rw-r--r--target-cris/op_helper.c7
-rw-r--r--target-cris/translate.c21
-rw-r--r--target-cris/translate_v10.c1
-rw-r--r--target-i386/bpt_helper.c3
-rw-r--r--target-i386/cpu-qom.h98
-rw-r--r--target-i386/cpu.c679
-rw-r--r--target-i386/cpu.h276
-rw-r--r--target-i386/excp_helper.c1
-rw-r--r--target-i386/fpu_helper.c11
-rw-r--r--target-i386/gdbstub.c1
-rw-r--r--target-i386/helper.c3
-rw-r--r--target-i386/hyperv.h4
-rw-r--r--target-i386/int_helper.c1
-rw-r--r--target-i386/kvm-stub.c1
-rw-r--r--target-i386/kvm.c779
-rw-r--r--target-i386/machine.c25
-rw-r--r--target-i386/mem_helper.c7
-rw-r--r--target-i386/misc_helper.c1
-rw-r--r--target-i386/mpx_helper.c1
-rw-r--r--target-i386/seg_helper.c7
-rw-r--r--target-i386/svm.h4
-rw-r--r--target-i386/svm_helper.c1
-rw-r--r--target-i386/trace-events7
-rw-r--r--target-i386/translate.c48
-rw-r--r--target-lm32/cpu-qom.h42
-rw-r--r--target-lm32/cpu.c1
-rw-r--r--target-lm32/cpu.h54
-rw-r--r--target-lm32/gdbstub.c1
-rw-r--r--target-lm32/helper.c3
-rw-r--r--target-lm32/machine.c3
-rw-r--r--target-lm32/op_helper.c7
-rw-r--r--target-lm32/translate.c26
-rw-r--r--target-m68k/cpu-qom.h34
-rw-r--r--target-m68k/cpu.c1
-rw-r--r--target-m68k/cpu.h47
-rw-r--r--target-m68k/gdbstub.c1
-rw-r--r--target-m68k/helper.c7
-rw-r--r--target-m68k/m68k-semi.c1
-rw-r--r--target-m68k/op_helper.c7
-rw-r--r--target-m68k/translate.c23
-rw-r--r--target-microblaze/cpu-qom.h44
-rw-r--r--target-microblaze/cpu.c1
-rw-r--r--target-microblaze/cpu.h56
-rw-r--r--target-microblaze/gdbstub.c1
-rw-r--r--target-microblaze/helper.c1
-rw-r--r--target-microblaze/mmu.c1
-rw-r--r--target-microblaze/op_helper.c13
-rw-r--r--target-microblaze/translate.c20
-rw-r--r--target-mips/cpu-qom.h37
-rw-r--r--target-mips/cpu.c1
-rw-r--r--target-mips/cpu.h205
-rw-r--r--target-mips/gdbstub.c9
-rw-r--r--target-mips/helper.c141
-rw-r--r--target-mips/helper.h22
-rw-r--r--target-mips/kvm.c14
-rw-r--r--target-mips/kvm_mips.h6
-rw-r--r--target-mips/machine.c14
-rw-r--r--target-mips/mips-defs.h6
-rw-r--r--target-mips/mips-semi.c1
-rw-r--r--target-mips/msa_helper.c89
-rw-r--r--target-mips/op_helper.c448
-rw-r--r--target-mips/translate.c192
-rw-r--r--target-mips/translate_init.c51
-rw-r--r--target-moxie/cpu.c1
-rw-r--r--target-moxie/cpu.h12
-rw-r--r--target-moxie/helper.c6
-rw-r--r--target-moxie/machine.c3
-rw-r--r--target-moxie/mmu.h5
-rw-r--r--target-moxie/translate.c22
-rw-r--r--target-openrisc/cpu.c1
-rw-r--r--target-openrisc/cpu.h12
-rw-r--r--target-openrisc/exception.c1
-rw-r--r--target-openrisc/exception.h6
-rw-r--r--target-openrisc/gdbstub.c1
-rw-r--r--target-openrisc/interrupt.c1
-rw-r--r--target-openrisc/interrupt_helper.c1
-rw-r--r--target-openrisc/machine.c3
-rw-r--r--target-openrisc/mmu.c1
-rw-r--r--target-openrisc/mmu_helper.c5
-rw-r--r--target-openrisc/sys_helper.c1
-rw-r--r--target-openrisc/translate.c24
-rw-r--r--target-ppc/cpu-qom.h182
-rw-r--r--target-ppc/cpu.h252
-rw-r--r--target-ppc/excp_helper.c330
-rw-r--r--target-ppc/fpu_helper.c128
-rw-r--r--target-ppc/gdbstub.c1
-rw-r--r--target-ppc/helper.h7
-rw-r--r--target-ppc/helper_regs.h81
-rw-r--r--target-ppc/int_helper.c1
-rw-r--r--target-ppc/kvm-stub.c1
-rw-r--r--target-ppc/kvm.c94
-rw-r--r--target-ppc/kvm_ppc.h15
-rw-r--r--target-ppc/machine.c10
-rw-r--r--target-ppc/mem_helper.c23
-rw-r--r--target-ppc/misc_helper.c42
-rw-r--r--target-ppc/mmu-hash32.c3
-rw-r--r--target-ppc/mmu-hash32.h8
-rw-r--r--target-ppc/mmu-hash64.c487
-rw-r--r--target-ppc/mmu-hash64.h16
-rw-r--r--target-ppc/mmu_helper.c90
-rw-r--r--target-ppc/timebase_helper.c11
-rw-r--r--target-ppc/trace-events5
-rw-r--r--target-ppc/translate.c1332
-rw-r--r--target-ppc/translate_init.c572
-rw-r--r--target-s390x/cc_helper.c1
-rw-r--r--target-s390x/cpu-qom.h46
-rw-r--r--target-s390x/cpu.c4
-rw-r--r--target-s390x/cpu.h195
-rw-r--r--target-s390x/fpu_helper.c29
-rw-r--r--target-s390x/gdbstub.c2
-rw-r--r--target-s390x/helper.c10
-rw-r--r--target-s390x/helper.h6
-rw-r--r--target-s390x/int_helper.c1
-rw-r--r--target-s390x/interrupt.c66
-rw-r--r--target-s390x/ioinst.c3
-rw-r--r--target-s390x/ioinst.h (renamed from include/hw/s390x/ioinst.h)20
-rw-r--r--target-s390x/kvm.c44
-rw-r--r--target-s390x/machine.c32
-rw-r--r--target-s390x/mem_helper.c10
-rw-r--r--target-s390x/misc_helper.c23
-rw-r--r--target-s390x/trace-events22
-rw-r--r--target-s390x/translate.c28
-rw-r--r--target-sh4/cpu-qom.h31
-rw-r--r--target-sh4/cpu.c2
-rw-r--r--target-sh4/cpu.h45
-rw-r--r--target-sh4/gdbstub.c1
-rw-r--r--target-sh4/helper.c1
-rw-r--r--target-sh4/op_helper.c14
-rw-r--r--target-sh4/translate.c26
-rw-r--r--target-sparc/asi.h311
-rw-r--r--target-sparc/cc_helper.c25
-rw-r--r--target-sparc/cpu-qom.h38
-rw-r--r--target-sparc/cpu.c8
-rw-r--r--target-sparc/cpu.h75
-rw-r--r--target-sparc/fop_helper.c230
-rw-r--r--target-sparc/gdbstub.c1
-rw-r--r--target-sparc/helper.c1
-rw-r--r--target-sparc/helper.h168
-rw-r--r--target-sparc/ldst_helper.c710
-rw-r--r--target-sparc/machine.c6
-rw-r--r--target-sparc/mmu_helper.c1
-rw-r--r--target-sparc/trace-events28
-rw-r--r--target-sparc/translate.c1302
-rw-r--r--target-tilegx/cpu.c1
-rw-r--r--target-tilegx/cpu.h11
-rw-r--r--target-tilegx/helper.c1
-rw-r--r--target-tilegx/opcode_tilegx.h6
-rw-r--r--target-tilegx/translate.c2
-rw-r--r--target-tricore/cpu-qom.h30
-rw-r--r--target-tricore/cpu.c1
-rw-r--r--target-tricore/cpu.h43
-rw-r--r--target-tricore/helper.c1
-rw-r--r--target-tricore/op_helper.c20
-rw-r--r--target-tricore/translate.c25
-rw-r--r--target-tricore/tricore-defs.h6
-rw-r--r--target-unicore32/cpu-qom.h30
-rw-r--r--target-unicore32/cpu.c3
-rw-r--r--target-unicore32/cpu.h44
-rw-r--r--target-unicore32/helper.c1
-rw-r--r--target-unicore32/op_helper.c5
-rw-r--r--target-unicore32/softmmu.c3
-rw-r--r--target-unicore32/translate.c21
-rw-r--r--target-xtensa/core-dc232b/core-isa.h7
-rw-r--r--target-xtensa/core-dc233c/core-isa.h7
-rw-r--r--target-xtensa/core-fsf/core-isa.h7
-rw-r--r--target-xtensa/cpu-qom.h39
-rw-r--r--target-xtensa/cpu.c1
-rw-r--r--target-xtensa/cpu.h51
-rw-r--r--target-xtensa/gdbstub.c2
-rw-r--r--target-xtensa/helper.c2
-rw-r--r--target-xtensa/op_helper.c12
-rw-r--r--target-xtensa/translate.c9
-rw-r--r--tcg/aarch64/tcg-target.h6
-rw-r--r--tcg/aarch64/tcg-target.inc.c40
-rw-r--r--tcg/arm/tcg-target.h5
-rw-r--r--tcg/arm/tcg-target.inc.c32
-rw-r--r--tcg/i386/tcg-target.h5
-rw-r--r--tcg/i386/tcg-target.inc.c67
-rw-r--r--tcg/ia64/tcg-target.h5
-rw-r--r--tcg/ia64/tcg-target.inc.c16
-rw-r--r--tcg/mips/tcg-target.h5
-rw-r--r--tcg/mips/tcg-target.inc.c21
-rw-r--r--tcg/optimize.c40
-rw-r--r--tcg/ppc/tcg-target.h5
-rw-r--r--tcg/ppc/tcg-target.inc.c48
-rw-r--r--tcg/s390/tcg-target.h5
-rw-r--r--tcg/s390/tcg-target.inc.c34
-rw-r--r--tcg/sparc/tcg-target.h5
-rw-r--r--tcg/sparc/tcg-target.inc.c21
-rw-r--r--tcg/tcg-common.c2
-rw-r--r--tcg/tcg-op.c18
-rw-r--r--tcg/tcg-op.h13
-rw-r--r--tcg/tcg.c770
-rw-r--r--tcg/tcg.h199
-rw-r--r--tcg/tci/tcg-target.h3
-rw-r--r--tcg/tci/tcg-target.inc.c18
-rw-r--r--tci.c13
-rw-r--r--tests/.gitignore6
-rw-r--r--tests/Makefile (renamed from tests/Makefile.include)75
-rw-r--r--tests/ac97-test.c1
-rw-r--r--tests/acpi-test-data/pc/APIC.cphpbin160 -> 0 bytes
-rw-r--r--tests/acpi-test-data/pc/DSDTbin6008 -> 5587 bytes
-rw-r--r--tests/acpi-test-data/pc/DSDT.bridgebin7867 -> 7446 bytes
-rw-r--r--tests/acpi-test-data/pc/DSDT.cphpbin6435 -> 0 bytes
-rw-r--r--tests/acpi-test-data/pc/DSDT.ipmikcsbin6080 -> 0 bytes
-rw-r--r--tests/acpi-test-data/q35/APIC.cphpbin160 -> 0 bytes
-rw-r--r--tests/acpi-test-data/q35/DSDTbin8770 -> 8357 bytes
-rw-r--r--tests/acpi-test-data/q35/DSDT.bridgebin8787 -> 8374 bytes
-rw-r--r--tests/acpi-test-data/q35/DSDT.cphpbin9197 -> 0 bytes
-rw-r--r--tests/acpi-test-data/q35/DSDT.ipmibtbin8845 -> 0 bytes
-rw-r--r--tests/ahci-test.c35
-rw-r--r--tests/bios-tables-test.c107
-rw-r--r--tests/boot-order-test.c1
-rw-r--r--tests/boot-sector.h6
-rw-r--r--tests/check-qdict.c1
-rw-r--r--tests/check-qfloat.c1
-rw-r--r--tests/check-qint.c1
-rw-r--r--tests/check-qjson.c11
-rw-r--r--tests/check-qlist.c1
-rw-r--r--tests/check-qnull.c73
-rw-r--r--tests/check-qom-interface.c1
-rw-r--r--tests/check-qom-proplist.c1
-rw-r--r--tests/check-qstring.c1
-rw-r--r--tests/data/test-qga-config8
-rw-r--r--tests/device-introspect-test.c1
-rw-r--r--tests/display-vga-test.c7
-rw-r--r--tests/docker/Makefile.include128
-rwxr-xr-xtests/docker/common.rc33
-rwxr-xr-xtests/docker/docker.py335
-rw-r--r--tests/docker/dockerfiles/centos6.docker6
-rw-r--r--tests/docker/dockerfiles/debian-bootstrap.docker21
-rwxr-xr-xtests/docker/dockerfiles/debian-bootstrap.pre87
-rw-r--r--tests/docker/dockerfiles/fedora.docker7
-rw-r--r--tests/docker/dockerfiles/ubuntu.docker11
-rwxr-xr-xtests/docker/run68
-rwxr-xr-xtests/docker/test-clang24
-rwxr-xr-xtests/docker/test-full17
-rwxr-xr-xtests/docker/test-mingw34
-rwxr-xr-xtests/docker/test-quick19
-rwxr-xr-xtests/docker/travis21
-rwxr-xr-xtests/docker/travis.py48
-rw-r--r--tests/drive_del-test.c4
-rw-r--r--tests/ds1338-test.c2
-rw-r--r--tests/e1000-test.c1
-rw-r--r--tests/e1000e-test.c478
-rw-r--r--tests/eepro100-test.c1
-rw-r--r--tests/endianness-test.c6
-rw-r--r--tests/es1370-test.c1
-rw-r--r--tests/fdc-test.c1
-rw-r--r--tests/fw_cfg-test.c1
-rw-r--r--tests/hd-geo-test.c1
-rw-r--r--tests/i440fx-test.c6
-rw-r--r--tests/i82801b11-test.c1
-rw-r--r--tests/ide-test.c45
-rw-r--r--tests/intel-hda-test.c7
-rw-r--r--tests/ioh3420-test.c1
-rw-r--r--tests/ipmi-bt-test.c1
-rw-r--r--tests/ipmi-kcs-test.c1
-rw-r--r--tests/ipoctal232-test.c1
-rw-r--r--tests/ivshmem-test.c2
-rw-r--r--tests/libqos/ahci.c1
-rw-r--r--tests/libqos/ahci.h4
-rw-r--r--tests/libqos/fw_cfg.c1
-rw-r--r--tests/libqos/i2c-imx.c1
-rw-r--r--tests/libqos/i2c-omap.c1
-rw-r--r--tests/libqos/libqos-pc.h4
-rw-r--r--tests/libqos/libqos.c1
-rw-r--r--tests/libqos/libqos.h4
-rw-r--r--tests/libqos/malloc-generic.c1
-rw-r--r--tests/libqos/malloc-pc.c1
-rw-r--r--tests/libqos/malloc.c2
-rw-r--r--tests/libqos/pci-pc.c1
-rw-r--r--tests/libqos/pci.c1
-rw-r--r--tests/libqos/usb.c1
-rw-r--r--tests/libqos/virtio-mmio.c14
-rw-r--r--tests/libqos/virtio-pci.c61
-rw-r--r--tests/libqos/virtio-pci.h17
-rw-r--r--tests/libqos/virtio.c49
-rw-r--r--tests/libqos/virtio.h78
-rw-r--r--tests/libqtest.c3
-rw-r--r--tests/m48t59-test.c1
-rw-r--r--tests/migration/.gitignore2
-rwxr-xr-xtests/migration/guestperf-batch.py26
-rwxr-xr-xtests/migration/guestperf-plot.py26
-rwxr-xr-xtests/migration/guestperf.py27
-rw-r--r--tests/migration/guestperf/__init__.py0
-rw-r--r--tests/migration/guestperf/comparison.py124
-rw-r--r--tests/migration/guestperf/engine.py439
-rw-r--r--tests/migration/guestperf/hardware.py62
-rw-r--r--tests/migration/guestperf/plot.py623
-rw-r--r--tests/migration/guestperf/progress.py117
-rw-r--r--tests/migration/guestperf/report.py98
-rw-r--r--tests/migration/guestperf/scenario.py95
-rw-r--r--tests/migration/guestperf/shell.py255
-rw-r--r--tests/migration/guestperf/timings.py55
-rw-r--r--tests/migration/stress.c367
-rw-r--r--tests/ne2000-test.c1
-rw-r--r--tests/nvme-test.c1
-rw-r--r--tests/pc-cpu-test.c1
-rw-r--r--tests/pcnet-test.c1
-rw-r--r--tests/postcopy-test.c530
-rw-r--r--tests/prom-env-test.c90
-rw-r--r--tests/pvpanic-test.c1
-rw-r--r--tests/pxe-test.c1
-rw-r--r--tests/q35-test.c1
-rw-r--r--tests/qapi-schema/args-bad-boxed.err1
-rw-r--r--tests/qapi-schema/args-bad-boxed.exit1
-rw-r--r--tests/qapi-schema/args-bad-boxed.json2
-rw-r--r--tests/qapi-schema/args-bad-boxed.out0
-rw-r--r--tests/qapi-schema/args-boxed-anon.err1
-rw-r--r--tests/qapi-schema/args-boxed-anon.exit1
-rw-r--r--tests/qapi-schema/args-boxed-anon.json2
-rw-r--r--tests/qapi-schema/args-boxed-anon.out0
-rw-r--r--tests/qapi-schema/args-boxed-empty.err1
-rw-r--r--tests/qapi-schema/args-boxed-empty.exit1
-rw-r--r--tests/qapi-schema/args-boxed-empty.json3
-rw-r--r--tests/qapi-schema/args-boxed-empty.out0
-rw-r--r--tests/qapi-schema/args-boxed-string.err1
-rw-r--r--tests/qapi-schema/args-boxed-string.exit1
-rw-r--r--tests/qapi-schema/args-boxed-string.json2
-rw-r--r--tests/qapi-schema/args-boxed-string.out0
-rw-r--r--tests/qapi-schema/args-union.err2
-rw-r--r--tests/qapi-schema/args-union.json3
-rw-r--r--tests/qapi-schema/event-boxed-empty.err1
-rw-r--r--tests/qapi-schema/event-boxed-empty.exit1
-rw-r--r--tests/qapi-schema/event-boxed-empty.json2
-rw-r--r--tests/qapi-schema/event-boxed-empty.out0
-rw-r--r--tests/qapi-schema/event-case.out1
-rw-r--r--tests/qapi-schema/flat-union-incomplete-branch.err1
-rw-r--r--tests/qapi-schema/flat-union-incomplete-branch.exit1
-rw-r--r--tests/qapi-schema/flat-union-incomplete-branch.json9
-rw-r--r--tests/qapi-schema/flat-union-incomplete-branch.out0
-rw-r--r--tests/qapi-schema/ident-with-escape.out2
-rw-r--r--tests/qapi-schema/indented-expr.out4
-rw-r--r--tests/qapi-schema/qapi-schema-test.json4
-rw-r--r--tests/qapi-schema/qapi-schema-test.out37
-rw-r--r--tests/qapi-schema/test-qapi.py11
-rwxr-xr-xtests/qemu-iotests/0042
-rwxr-xr-xtests/qemu-iotests/0125
-rw-r--r--tests/qemu-iotests/023.out2160
-rw-r--r--tests/qemu-iotests/026.out50
-rw-r--r--tests/qemu-iotests/026.out.nocache50
-rwxr-xr-xtests/qemu-iotests/0342
-rw-r--r--tests/qemu-iotests/039.out20
-rwxr-xr-xtests/qemu-iotests/04157
-rwxr-xr-xtests/qemu-iotests/04826
-rw-r--r--tests/qemu-iotests/048.out6
-rwxr-xr-xtests/qemu-iotests/0524
-rw-r--r--tests/qemu-iotests/052.out4
-rw-r--r--tests/qemu-iotests/061.out8
-rw-r--r--tests/qemu-iotests/071.out8
-rwxr-xr-xtests/qemu-iotests/07712
-rw-r--r--tests/qemu-iotests/077.out26
-rwxr-xr-xtests/qemu-iotests/0834
-rw-r--r--tests/qemu-iotests/087.out12
-rw-r--r--tests/qemu-iotests/089.out2
-rwxr-xr-xtests/qemu-iotests/0952
-rw-r--r--tests/qemu-iotests/0963
-rwxr-xr-xtests/qemu-iotests/100145
-rw-r--r--tests/qemu-iotests/100.out89
-rwxr-xr-xtests/qemu-iotests/1094
-rw-r--r--tests/qemu-iotests/109.out12
-rw-r--r--tests/qemu-iotests/13635
-rw-r--r--tests/qemu-iotests/136.out4
-rw-r--r--tests/qemu-iotests/137.out4
-rw-r--r--tests/qemu-iotests/141.out4
-rw-r--r--tests/qemu-iotests/144.out2
-rwxr-xr-xtests/qemu-iotests/14912
-rw-r--r--tests/qemu-iotests/149.out240
-rwxr-xr-xtests/qemu-iotests/154305
-rw-r--r--tests/qemu-iotests/154.out285
-rwxr-xr-xtests/qemu-iotests/155261
-rw-r--r--tests/qemu-iotests/155.out5
-rwxr-xr-xtests/qemu-iotests/156174
-rw-r--r--tests/qemu-iotests/156.out48
-rwxr-xr-xtests/qemu-iotests/15789
-rw-r--r--tests/qemu-iotests/157.out22
-rwxr-xr-xtests/qemu-iotests/16296
-rw-r--r--tests/qemu-iotests/162.out17
-rw-r--r--tests/qemu-iotests/README3
-rw-r--r--tests/qemu-iotests/common15
-rw-r--r--tests/qemu-iotests/common.config21
-rw-r--r--tests/qemu-iotests/common.filter11
-rw-r--r--tests/qemu-iotests/common.rc69
-rw-r--r--tests/qemu-iotests/group7
-rw-r--r--tests/qemu-iotests/iotests.py163
-rw-r--r--tests/qht-bench.c487
-rw-r--r--tests/qom-test.c1
-rw-r--r--tests/rcutorture.c1
-rw-r--r--tests/rtc-test.c1
-rw-r--r--tests/rtl8139-test.c1
-rw-r--r--tests/spapr-phb-test.c1
-rw-r--r--tests/tcg/xtensa/linker.ld.S2
-rw-r--r--tests/tco-test.c1
-rw-r--r--tests/test-aio.c1
-rw-r--r--tests/test-base64.c1
-rw-r--r--tests/test-bitops.c73
-rw-r--r--tests/test-blockjob-txn.c15
-rw-r--r--tests/test-blockjob.c147
-rw-r--r--tests/test-clone-visitor.c206
-rw-r--r--tests/test-coroutine.c76
-rw-r--r--tests/test-crypto-cipher.c1
-rw-r--r--tests/test-crypto-hash.c54
-rw-r--r--tests/test-crypto-secret.c7
-rw-r--r--tests/test-crypto-xts.c18
-rw-r--r--tests/test-cutils.c1
-rw-r--r--tests/test-filter-mirror.c1
-rw-r--r--tests/test-filter-redirector.c7
-rw-r--r--tests/test-hbitmap.c7
-rw-r--r--tests/test-int128.c1
-rw-r--r--tests/test-io-channel-socket.c2
-rw-r--r--tests/test-io-task.c9
-rw-r--r--tests/test-iov.c1
-rw-r--r--tests/test-logging.c134
-rw-r--r--tests/test-mul64.c1
-rw-r--r--tests/test-netfilter.c1
-rw-r--r--tests/test-opts-visitor.c10
-rw-r--r--tests/test-qdev-global-props.c1
-rw-r--r--tests/test-qdist.c389
-rw-r--r--tests/test-qemu-opts.c1
-rw-r--r--tests/test-qga.c109
-rw-r--r--tests/test-qht-par.c55
-rw-r--r--tests/test-qht.c162
-rw-r--r--tests/test-qmp-commands.c34
-rw-r--r--tests/test-qmp-event.c1
-rw-r--r--tests/test-qmp-input-strict.c35
-rw-r--r--tests/test-qmp-input-visitor.c62
-rw-r--r--tests/test-qmp-output-visitor.c126
-rw-r--r--tests/test-rcu-list.c1
-rw-r--r--tests/test-rfifolock.c1
-rw-r--r--tests/test-string-input-visitor.c46
-rw-r--r--tests/test-string-output-visitor.c100
-rw-r--r--tests/test-thread-pool.c5
-rw-r--r--tests/test-throttle.c81
-rw-r--r--tests/test-timed-average.c1
-rw-r--r--tests/test-visitor-serialization.c44
-rw-r--r--tests/test-vmstate.c56
-rw-r--r--tests/test-write-threshold.c1
-rw-r--r--tests/test-x86-cpuid.c1
-rw-r--r--tests/tmp105-test.c1
-rw-r--r--tests/tpci200-test.c1
-rw-r--r--tests/usb-hcd-ehci-test.c1
-rw-r--r--tests/usb-hcd-ohci-test.c1
-rw-r--r--tests/usb-hcd-uhci-test.c1
-rw-r--r--tests/usb-hcd-xhci-test.c1
-rw-r--r--tests/vhost-user-bridge.c54
-rw-r--r--tests/vhost-user-test.c158
-rw-r--r--tests/virtio-9p-test.c1
-rw-r--r--tests/virtio-balloon-test.c1
-rw-r--r--tests/virtio-blk-test.c102
-rw-r--r--tests/virtio-console-test.c7
-rw-r--r--tests/virtio-net-test.c31
-rw-r--r--tests/virtio-rng-test.c1
-rw-r--r--tests/virtio-scsi-test.c62
-rw-r--r--tests/virtio-serial-test.c1
-rw-r--r--tests/vmxnet3-test.c1
-rw-r--r--tests/wdt_ib700-test.c7
-rw-r--r--thread-pool.c2
-rw-r--r--thunk.c32
-rw-r--r--trace-events1811
-rw-r--r--trace/Makefile.objs29
-rw-r--r--trace/control-internal.h49
-rw-r--r--trace/control-target.c53
-rw-r--r--trace/control.c74
-rw-r--r--trace/control.h106
-rw-r--r--trace/event-internal.h6
-rw-r--r--trace/ftrace.h4
-rw-r--r--trace/mem-internal.h46
-rw-r--r--trace/mem.h34
-rw-r--r--trace/qmp.c148
-rw-r--r--translate-all.c530
-rw-r--r--translate-all.h5
-rw-r--r--translate-common.c1
-rw-r--r--ui/console-gl.c5
-rw-r--r--ui/console.c9
-rw-r--r--ui/curses_keys.h2
-rw-r--r--ui/cursor.c10
-rw-r--r--ui/egl-helpers.c36
-rw-r--r--ui/gtk-egl.c1
-rw-r--r--ui/gtk-gl-area.c1
-rw-r--r--ui/gtk.c120
-rw-r--r--ui/input-linux.c269
-rw-r--r--ui/keymaps.h6
-rw-r--r--ui/qemu-pixman.c13
-rw-r--r--ui/sdl2-2d.c3
-rw-r--r--ui/sdl2-gl.c1
-rw-r--r--ui/sdl_zoom.c1
-rw-r--r--ui/sdl_zoom.h6
-rw-r--r--ui/shader.c8
-rw-r--r--ui/spice-display.c29
-rw-r--r--ui/trace-events48
-rw-r--r--ui/vnc-auth-sasl.h9
-rw-r--r--ui/vnc-auth-vencrypt.h7
-rw-r--r--ui/vnc-enc-tight.c48
-rw-r--r--ui/vnc-enc-tight.h6
-rw-r--r--ui/vnc-enc-zrle.h4
-rw-r--r--ui/vnc-enc-zywrle.h4
-rw-r--r--ui/vnc-palette.c1
-rw-r--r--ui/vnc-ws.c1
-rw-r--r--ui/vnc-ws.h6
-rw-r--r--ui/vnc.c125
-rw-r--r--ui/vnc.h7
-rw-r--r--user-exec.c197
-rw-r--r--util/Makefile.objs3
-rw-r--r--util/acl.c9
-rw-r--r--util/buffer.c5
-rw-r--r--util/coroutine-gthread.c1
-rw-r--r--util/cutils.c15
-rw-r--r--util/error.c2
-rw-r--r--util/hbitmap.c4
-rw-r--r--util/iov.c3
-rw-r--r--util/log.c163
-rw-r--r--util/memfd.c3
-rw-r--r--util/mmap-alloc.c4
-rw-r--r--util/module.c6
-rw-r--r--util/osdep.c36
-rw-r--r--util/oslib-posix.c33
-rw-r--r--util/oslib-win32.c3
-rw-r--r--util/qdist.c397
-rw-r--r--util/qemu-coroutine-io.c2
-rw-r--r--util/qemu-coroutine-lock.c26
-rw-r--r--util/qemu-coroutine-sleep.c2
-rw-r--r--util/qemu-coroutine.c10
-rw-r--r--util/qemu-sockets.c151
-rw-r--r--util/qht.c844
-rw-r--r--util/range.c73
-rw-r--r--util/rfifolock.c2
-rw-r--r--util/throttle.c13
-rw-r--r--util/trace-events13
-rw-r--r--util/uri.c1
-rw-r--r--vl.c480
-rw-r--r--xen-hvm.c39
-rw-r--r--xen-mapcache.c1
2663 files changed, 39479 insertions, 151056 deletions
diff --git a/.gitignore b/.gitignore
index 88ec2497b..88a80ff4a 100644
--- a/.gitignore
+++ b/.gitignore
@@ -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
@@ -95,10 +94,6 @@
/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
@@ -113,5 +108,4 @@
cscope.*
tags
TAGS
-docker-src.*
*~
diff --git a/.travis.yml b/.travis.yml
index f30b10e4f..50ac17f4d 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -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
diff --git a/CODING_STYLE b/CODING_STYLE
index e7fde1500..3c6978f83 100644
--- a/CODING_STYLE
+++ b/CODING_STYLE
@@ -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 20a910168..058aa8fd4 100644
--- 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
diff --git a/MAINTAINERS b/MAINTAINERS
index b6fb84e82..81e7fac2f 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -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/
diff --git a/Makefile b/Makefile
index 50b4b3afb..1d076a9d8 100644
--- 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
diff --git a/Makefile.objs b/Makefile.objs
index 6d5ddcfd3..8f705f620 100644
--- a/Makefile.objs
+++ b/Makefile.objs
@@ -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
diff --git a/Makefile.target b/Makefile.target
index a440bcb5b..34ddb7e76 100644
--- a/Makefile.target
+++ b/Makefile.target
@@ -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 24ba9a38d..6a6a3d8e3 100644
--- a/VERSION
+++ b/VERSION
@@ -1 +1 @@
-2.7.0
+2.6.1
diff --git a/accel.c b/accel.c
index 403eb5e94..0510b90f6 100644
--- 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;
}
diff --git a/aio-posix.c b/aio-posix.c
index 43162a9f2..6006122e0 100644
--- a/aio-posix.c
+++ b/aio-posix.c
@@ -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;
diff --git a/aio-win32.c b/aio-win32.c
index c8c249e26..6aaa32a14 100644
--- a/aio-win32.c
+++ b/aio-win32.c
@@ -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)
{
}
diff --git a/arch_init.c b/arch_init.c
index fa059731e..e3bb1b3ac 100644
--- a/arch_init.c
+++ b/arch_init.c
@@ -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 3bca9b0ad..b4bf205a0 100644
--- 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);
diff --git a/audio/audio.c b/audio/audio.c
index c845a44f0..e60c124de 100644
--- a/audio/audio.c
+++ b/audio/audio.c
@@ -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;
diff --git a/audio/audio.h b/audio/audio.h
index c3c51988f..b41a97053 100644
--- a/audio/audio.h
+++ b/audio/audio.h
@@ -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 */
diff --git a/audio/audio_int.h b/audio/audio_int.h
index 5bcb1c60e..566df5edf 100644
--- a/audio/audio_int.h
+++ b/audio/audio_int.h
@@ -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 */
diff --git a/audio/audio_pt_int.h b/audio/audio_pt_int.h
index 4c0c15b9a..0dfff76aa 100644
--- a/audio/audio_pt_int.h
+++ b/audio/audio_pt_int.h
@@ -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 */
diff --git a/audio/coreaudio.c b/audio/coreaudio.c
index c75142084..d4ad22459 100644
--- a/audio/coreaudio.c
+++ b/audio/coreaudio.c
@@ -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;
}
diff --git a/audio/mixeng.c b/audio/mixeng.c
index 66c0328d4..61ef8691a 100644
--- a/audio/mixeng.c
+++ b/audio/mixeng.c
@@ -24,7 +24,6 @@
*/
#include "qemu/osdep.h"
#include "qemu-common.h"
-#include "qemu/bswap.h"
#include "audio.h"
#define AUDIO_CAP "mixeng"
diff --git a/audio/mixeng.h b/audio/mixeng.h
index b53a5ef99..9de443b01 100644
--- a/audio/mixeng.h
+++ b/audio/mixeng.h
@@ -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 */
diff --git a/audio/noaudio.c b/audio/noaudio.c
index 9ca9eaf01..b360c199a 100644
--- a/audio/noaudio.c
+++ b/audio/noaudio.c
@@ -23,7 +23,6 @@
*/
#include "qemu/osdep.h"
#include "qemu-common.h"
-#include "qemu/host-utils.h"
#include "audio.h"
#include "qemu/timer.h"
diff --git a/audio/ossaudio.c b/audio/ossaudio.c
index 0edd7ea5f..a0d9cda1e 100644
--- a/audio/ossaudio.c
+++ b/audio/ossaudio.c
@@ -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"
diff --git a/audio/paaudio.c b/audio/paaudio.c
index 65beb6f01..57678e72e 100644
--- a/audio/paaudio.c
+++ b/audio/paaudio.c
@@ -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);
}
diff --git a/audio/spiceaudio.c b/audio/spiceaudio.c
index 5580e7630..dea71d37a 100644
--- a/audio/spiceaudio.c
+++ b/audio/spiceaudio.c
@@ -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
index 517359039..000000000
--- a/audio/trace-events
+++ /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"
diff --git a/audio/wavaudio.c b/audio/wavaudio.c
index 341eec312..345952e51 100644
--- a/audio/wavaudio.c
+++ b/audio/wavaudio.c
@@ -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"
diff --git a/backends/hostmem.c b/backends/hostmem.c
index b7a208d0d..6e28be11e 100644
--- a/backends/hostmem.c
+++ b/backends/hostmem.c
@@ -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;
diff --git a/backends/msmouse.c b/backends/msmouse.c
index aeb905562..8dea5a130 100644
--- a/backends/msmouse.c
+++ b/backends/msmouse.c
@@ -25,51 +25,16 @@
#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;
}
diff --git a/backends/rng-random.c b/backends/rng-random.c
index e2a49b057..2e44e2519 100644
--- a/backends/rng-random.c
+++ b/backends/rng-random.c
@@ -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 30d64e6ca..d4939b49b 100644
--- 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);
-}
diff --git a/block/Makefile.objs b/block/Makefile.objs
index 2593a2f8a..44a541622 100644
--- a/block/Makefile.objs
+++ b/block/Makefile.objs
@@ -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)
diff --git a/block/archipelago.c b/block/archipelago.c
index 37b8aca78..b9f5e69d4 100644
--- a/block/archipelago.c
+++ b/block/archipelago.c
@@ -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)
diff --git a/block/backup.c b/block/backup.c
index 2c0532314..370c28525 100644
--- a/block/backup.c
+++ b/block/backup.c
@@ -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);
}
}
diff --git a/block/blkdebug.c b/block/blkdebug.c
index d5db16681..20d25bda6 100644
--- a/block/blkdebug.c
+++ b/block/blkdebug.c
@@ -37,10 +37,6 @@
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,
diff --git a/block/blkreplay.c b/block/blkreplay.c
index 30f9d5ff6..42f1813af 100755
--- a/block/blkreplay.c
+++ b/block/blkreplay.c
@@ -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,
};
diff --git a/block/blkverify.c b/block/blkverify.c
index da62d7596..9414b7a84 100644
--- a/block/blkverify.c
+++ b/block/blkverify.c
@@ -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,
};
diff --git a/block/block-backend.c b/block/block-backend.c
index effa03892..16c9d5e0f 100644
--- a/block/block-backend.c
+++ b/block/block-backend.c
@@ -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;
-}
diff --git a/block/bochs.c b/block/bochs.c
index 8c9652ebe..af8b7abdf 100644
--- a/block/bochs.c
+++ b/block/bochs.c
@@ -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,
};
diff --git a/block/cloop.c b/block/cloop.c
index 7b75f7ef7..a84f14019 100644
--- a/block/cloop.c
+++ b/block/cloop.c
@@ -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,
};
diff --git a/block/commit.c b/block/commit.c
index 553e18da5..cba0e8c1e 100644
--- a/block/commit.c
+++ b/block/commit.c
@@ -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);
}
diff --git a/block/crypto.c b/block/crypto.c
index 7f61e1268..1903e84fb 100644
--- a/block/crypto.c
+++ b/block/crypto.c
@@ -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)
diff --git a/block/curl.c b/block/curl.c
index 426fb4d67..5a8f8b623 100644
--- a/block/curl.c
+++ b/block/curl.c
@@ -36,16 +36,10 @@
// #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,
diff --git a/block/dirty-bitmap.c b/block/dirty-bitmap.c
index f2bfdcfde..4902ca557 100644
--- a/block/dirty-bitmap.c
+++ b/block/dirty-bitmap.c
@@ -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) {
diff --git a/block/dmg.c b/block/dmg.c
index b0ed89baa..a496eb7c9 100644
--- a/block/dmg.c
+++ b/block/dmg.c
@@ -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,
};
diff --git a/block/gluster.c b/block/gluster.c
index 01b479fbb..a8aaacf64 100644
--- a/block/gluster.c
+++ b/block/gluster.c
@@ -11,27 +11,7 @@
#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,
};
diff --git a/block/io.c b/block/io.c
index 420944d80..d02e0d576 100644
--- a/block/io.c
+++ b/block/io.c
@@ -27,54 +27,118 @@
#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;
+
+ bs->io_limits_enabled = false;
- QLIST_FOREACH(c, &bs->parents, next_parent) {
- if (c->role->drained_end) {
- c->role->drained_end(c);
+ 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;
- assert(is_power_of_2(align));
- assert((offset & (align - 1)) == 0);
- assert((bytes & (align - 1)) == 0);
+ int64_t sector_num = offset >> BDRV_SECTOR_BITS;
+ unsigned int nb_sectors = bytes >> BDRV_SECTOR_BITS;
+
+ 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(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_readv(BdrvChild *child, 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)
{
- 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);
+ int max_write_zeroes = MIN_NON_ZERO(bs->bl.max_write_zeroes,
+ BDRV_REQUEST_MAX_SECTORS);
- 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);
-
- 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,
+ };
-static int coroutine_fn
-bdrv_co_rw_vmstate(BlockDriverState *bs, QEMUIOVector *qiov, int64_t pos,
- bool is_read)
+ qemu_iovec_init_external(&qiov, &iov, 1);
+ return bdrv_writev_vmstate(bs, &qiov, pos);
+}
+
+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);
+
+ // 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;
+ }
- 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);
+ 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;
+
+ 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);
+ }
- 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);
+ 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;
+ }
+
+ /* limit request size */
+ if (num > max_discard) {
+ num = max_discard;
+ }
- if (bs->drv->bdrv_co_pdiscard) {
- ret = bs->drv->bdrv_co_pdiscard(bs, offset, num);
+ 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));
}
diff --git a/block/iscsi.c b/block/iscsi.c
index 95ce9e139..0466c30fd 100644
--- a/block/iscsi.c
+++ b/block/iscsi.c
@@ -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__
diff --git a/block/linux-aio.c b/block/linux-aio.c
index e906abebb..805757e02 100644
--- a/block/linux-aio.c
+++ b/block/linux-aio.c
@@ -11,10 +11,8 @@
#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>
@@ -28,10 +26,11 @@
*/
#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) {
diff --git a/block/mirror.c b/block/mirror.c
index e0b3f4180..039f48125 100644
--- a/block/mirror.c
+++ b/block/mirror.c
@@ -20,12 +20,11 @@
#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) {
diff --git a/block/nbd-client.c b/block/nbd-client.c
index 2cf3237ef..6f6df468f 100644
--- a/block/nbd-client.c
+++ b/block/nbd-client.c
@@ -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);
diff --git a/block/nbd-client.h b/block/nbd-client.h
index 044aca453..124361270 100644
--- a/block/nbd-client.h
+++ b/block/nbd-client.h
@@ -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,
diff --git a/block/nbd.c b/block/nbd.c
index 6bc06d619..f7ea3b360 100644
--- a/block/nbd.c
+++ b/block/nbd.c
@@ -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,
diff --git a/block/nfs.c b/block/nfs.c
index 8602a4421..60be45e8d 100644
--- a/block/nfs.c
+++ b/block/nfs.c
@@ -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)
diff --git a/block/null.c b/block/null.c
index b511010ba..396500bab 100644
--- a/block/null.c
+++ b/block/null.c
@@ -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)
diff --git a/block/parallels.c b/block/parallels.c
index 2ccefa7d8..324ed43ac 100644
--- a/block/parallels.c
+++ b/block/parallels.c
@@ -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;
}
diff --git a/block/qapi.c b/block/qapi.c
index 6f947e3e6..c5f6ba643 100644
--- a/block/qapi.c
+++ b/block/qapi.c
@@ -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,
diff --git a/block/qcow.c b/block/qcow.c
index 6f9b2e2d2..60ddb12ec 100644
--- a/block/qcow.c
+++ b/block/qcow.c
@@ -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;
}
diff --git a/block/qcow2-cache.c b/block/qcow2-cache.c
index 6eaefeddc..0fe8edae4 100644
--- a/block/qcow2-cache.c
+++ b/block/qcow2-cache.c
@@ -24,6 +24,11 @@
/* 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) {
diff --git a/block/qcow2-cluster.c b/block/qcow2-cluster.c
index f94183529..22bdb4750 100644
--- a/block/qcow2-cluster.c
+++ b/block/qcow2-cluster.c
@@ -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) {
diff --git a/block/qcow2-refcount.c b/block/qcow2-refcount.c
index cbfb3fe06..ca6094ff5 100644
--- a/block/qcow2-refcount.c
+++ b/block/qcow2-refcount.c
@@ -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++) {
diff --git a/block/qcow2-snapshot.c b/block/qcow2-snapshot.c
index 032424322..5f4a17e47 100644
--- a/block/qcow2-snapshot.c
+++ b/block/qcow2-snapshot.c
@@ -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");
diff --git a/block/qcow2.c b/block/qcow2.c
index 91ef4dfef..470734be9 100644
--- a/block/qcow2.c
+++ b/block/qcow2.c
@@ -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,
diff --git a/block/qcow2.h b/block/qcow2.h
index b36a7bf8a..a063a3c1a 100644
--- a/block/qcow2.h
+++ b/block/qcow2.h
@@ -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);
diff --git a/block/qed-check.c b/block/qed-check.c
index dcd4f036b..622f30897 100644
--- a/block/qed-check.c
+++ b/block/qed-check.c
@@ -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 */
diff --git a/block/qed-table.c b/block/qed-table.c
index 1a731dff5..802945f5e 100644
--- a/block/qed-table.c
+++ b/block/qed-table.c
@@ -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);
diff --git a/block/qed.c b/block/qed.c
index 426f3cb44..0af52741d 100644
--- a/block/qed.c
+++ b/block/qed.c
@@ -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,
diff --git a/block/quorum.c b/block/quorum.c
index 9cf876fb3..da15465a9 100644
--- a/block/quorum.c
+++ b/block/quorum.c
@@ -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,
diff --git a/include/block/raw-aio.h b/block/raw-aio.h
index a4cdbbf1b..811e37501 100644
--- a/include/block/raw-aio.h
+++ b/block/raw-aio.h
@@ -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 */
@@ -36,18 +35,15 @@
/* 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
diff --git a/block/raw-posix.c b/block/raw-posix.c
index 6ed754739..906d5c941 100644
--- a/block/raw-posix.c
+++ b/block/raw-posix.c
@@ -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,
diff --git a/block/raw-win32.c b/block/raw-win32.c
index 56f45fea9..fd2389153 100644
--- a/block/raw-win32.c
+++ b/block/raw-win32.c
@@ -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,
diff --git a/block/raw_bsd.c b/block/raw_bsd.c
index 588d4080f..a6cc7e991 100644
--- a/block/raw_bsd.c
+++ b/block/raw_bsd.c
@@ -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,
diff --git a/block/rbd.c b/block/rbd.c
index 0106fea45..5bc5b3253 100644
--- a/block/rbd.c
+++ b/block/rbd.c
@@ -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,
diff --git a/block/sheepdog.c b/block/sheepdog.c
index 66e1cb2b2..33e0a3382 100644
--- a/block/sheepdog.c
+++ b/block/sheepdog.c
@@ -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,
diff --git a/block/snapshot.c b/block/snapshot.c
index bf5c2ca5e..e9d721df6 100644
--- a/block/snapshot.c
+++ b/block/snapshot.c
@@ -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;
}
diff --git a/block/ssh.c b/block/ssh.c
index 5ce12b633..06928ed93 100644
--- a/block/ssh.c
+++ b/block/ssh.c
@@ -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)
diff --git a/block/stream.c b/block/stream.c
index 31874817c..332b9a183 100644
--- a/block/stream.c
+++ b/block/stream.c
@@ -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);
}
diff --git a/block/throttle-groups.c b/block/throttle-groups.c
index 59545e287..4920e0949 100644
--- a/block/throttle-groups.c
+++ b/block/throttle-groups.c
@@ -23,14 +23,13 @@
*/
#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.
*
@@ -40,26 +39,26 @@
* 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
index 05fa13c89..000000000
--- a/block/trace-events
+++ /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"
diff --git a/block/vdi.c b/block/vdi.c
index 8a1cf9792..75d4819ed 100644
--- a/block/vdi.c
+++ b/block/vdi.c
@@ -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,
diff --git a/block/vhdx-endian.c b/block/vhdx-endian.c
index c306b90d5..da33cd38e 100644
--- a/block/vhdx-endian.c
+++ b/block/vhdx-endian.c
@@ -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>
diff --git a/block/vhdx-log.c b/block/vhdx-log.c
index 02eb10431..7ea7187fc 100644
--- a/block/vhdx-log.c
+++ b/block/vhdx-log.c
@@ -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);
diff --git a/block/vhdx.c b/block/vhdx.c
index 75ef2b1c2..2b7b33240 100644
--- a/block/vhdx.c
+++ b/block/vhdx.c
@@ -22,11 +22,11 @@
#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;
diff --git a/block/vmdk.c b/block/vmdk.c
index 46d474e44..45f9d3c5b 100644
--- a/block/vmdk.c
+++ b/block/vmdk.c
@@ -30,10 +30,10 @@
#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,
diff --git a/block/vpc.c b/block/vpc.c
index 43707ed22..3e2ea698d 100644
--- a/block/vpc.c
+++ b/block/vpc.c
@@ -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,
diff --git a/block/vvfat.c b/block/vvfat.c
index ba2620f3c..183fc4f04 100644
--- a/block/vvfat.c
+++ b/block/vvfat.c
@@ -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,
};
diff --git a/block/win32-aio.c b/block/win32-aio.c
index 95e3ab154..2d509a9a7 100644
--- a/block/win32-aio.c
+++ b/block/win32-aio.c
@@ -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>
diff --git a/blockdev.c b/blockdev.c
index 21614004d..260a6f5e0 100644
--- a/blockdev.c
+++ b/blockdev.c
@@ -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;
diff --git a/blockjob.c b/blockjob.c
index a5ba3bee5..9fc37ca96 100644
--- a/blockjob.c
+++ b/blockjob.c
@@ -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;
diff --git a/bootdevice.c b/bootdevice.c
index 33e3029e4..2e83ff05e 100644
--- a/bootdevice.c
+++ b/bootdevice.c
@@ -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,
diff --git a/bsd-user/elfload.c b/bsd-user/elfload.c
index 41a130929..898ee0547 100644
--- a/bsd-user/elfload.c
+++ b/bsd-user/elfload.c
@@ -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"
diff --git a/bsd-user/i386/target_syscall.h b/bsd-user/i386/target_syscall.h
index 8f201386a..82d1c58ca 100644
--- a/bsd-user/i386/target_syscall.h
+++ b/bsd-user/i386/target_syscall.h
@@ -162,4 +162,4 @@ struct target_vm86plus_struct {
#define UNAME_MACHINE "i386"
-#endif /* TARGET_SYSCALL_H */
+#endif /* TARGET_SYSCALL_H */
diff --git a/bsd-user/main.c b/bsd-user/main.c
index 0fb08e405..27854c1f9 100644
--- a/bsd-user/main.c
+++ b/bsd-user/main.c
@@ -17,23 +17,18 @@
* 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;
diff --git a/bsd-user/mmap.c b/bsd-user/mmap.c
index 610f91b28..6ab533470 100644
--- a/bsd-user/mmap.c
+++ b/bsd-user/mmap.c
@@ -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"
diff --git a/bsd-user/qemu.h b/bsd-user/qemu.h
index 2b2b9184e..03b502ad3 100644
--- a/bsd-user/qemu.h
+++ b/bsd-user/qemu.h
@@ -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
}
diff --git a/bsd-user/sparc/target_syscall.h b/bsd-user/sparc/target_syscall.h
index dfdf9f82f..c7eec6ba6 100644
--- a/bsd-user/sparc/target_syscall.h
+++ b/bsd-user/sparc/target_syscall.h
@@ -11,4 +11,4 @@ struct target_pt_regs {
#define UNAME_MACHINE "sun4"
-#endif /* TARGET_SYSCALL_H */
+#endif /* TARGET_SYSCALL_H */
diff --git a/bsd-user/sparc64/target_syscall.h b/bsd-user/sparc64/target_syscall.h
index 3a9f4c2ef..2f06100ae 100644
--- a/bsd-user/sparc64/target_syscall.h
+++ b/bsd-user/sparc64/target_syscall.h
@@ -12,4 +12,4 @@ struct target_pt_regs {
#define UNAME_MACHINE "sun4u"
-#endif /* TARGET_SYSCALL_H */
+#endif /* TARGET_SYSCALL_H */
diff --git a/bsd-user/syscall.c b/bsd-user/syscall.c
index 66492aaf5..47cf865a3 100644
--- a/bsd-user/syscall.c
+++ b/bsd-user/syscall.c
@@ -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;
diff --git a/bsd-user/x86_64/target_syscall.h b/bsd-user/x86_64/target_syscall.h
index 211ce29e9..85a976697 100644
--- a/bsd-user/x86_64/target_syscall.h
+++ b/bsd-user/x86_64/target_syscall.h
@@ -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 */
diff --git a/configure b/configure
index 4b808f9d1..60e3c0dd6 100755
--- 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"
diff --git a/contrib/ivshmem-client/ivshmem-client.h b/contrib/ivshmem-client/ivshmem-client.h
index 5ee942262..54cde17d9 100644
--- a/contrib/ivshmem-client/ivshmem-client.h
+++ b/contrib/ivshmem-client/ivshmem-client.h
@@ -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_ */
diff --git a/contrib/ivshmem-server/ivshmem-server.c b/contrib/ivshmem-server/ivshmem-server.c
index e2f295bd4..172db78b3 100644
--- a/contrib/ivshmem-server/ivshmem-server.c
+++ b/contrib/ivshmem-server/ivshmem-server.c
@@ -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>
diff --git a/contrib/ivshmem-server/ivshmem-server.h b/contrib/ivshmem-server/ivshmem-server.h
index 4af08e1bb..d37ca8526 100644
--- a/contrib/ivshmem-server/ivshmem-server.h
+++ b/contrib/ivshmem-server/ivshmem-server.h
@@ -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_ */
diff --git a/cpu-exec-common.c b/cpu-exec-common.c
index 0cb4ae60e..1b1731cd8 100644
--- a/cpu-exec-common.c
+++ b/cpu-exec-common.c
@@ -20,14 +20,16 @@
#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);
}
diff --git a/cpu-exec.c b/cpu-exec.c
index 5d9710a1e..bbfcbfb54 100644
--- a/cpu-exec.c
+++ b/cpu-exec.c
@@ -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 84c3520d4..cbeb1f613 100644
--- 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)
diff --git a/cputlb.c b/cputlb.c
index d068ee597..466663b56 100644
--- a/cputlb.c
+++ b/cputlb.c
@@ -28,10 +28,7 @@
#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
diff --git a/crypto/Makefile.objs b/crypto/Makefile.objs
index a36d2d9bd..0737f4811 100644
--- a/crypto/Makefile.objs
+++ b/crypto/Makefile.objs
@@ -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
diff --git a/crypto/afsplit.c b/crypto/afsplit.c
index 825e2cff2..8074913cd 100644
--- a/crypto/afsplit.c
+++ b/crypto/afsplit.c
@@ -24,7 +24,6 @@
*/
#include "qemu/osdep.h"
-#include "qemu/bswap.h"
#include "crypto/afsplit.h"
#include "crypto/random.h"
diff --git a/crypto/block-luks.c b/crypto/block-luks.c
index aba445564..439f89230 100644
--- a/crypto/block-luks.c
+++ b/crypto/block-luks.c
@@ -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,
diff --git a/crypto/block-luks.h b/crypto/block-luks.h
index b2d8a35c1..0934138aa 100644
--- a/crypto/block-luks.h
+++ b/crypto/block-luks.h
@@ -18,11 +18,11 @@
*
*/
-#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__ */
diff --git a/crypto/block-qcow.h b/crypto/block-qcow.h
index 3e2c0a851..569f83610 100644
--- a/crypto/block-qcow.h
+++ b/crypto/block-qcow.h
@@ -18,11 +18,11 @@
*
*/
-#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__ */
diff --git a/crypto/block.c b/crypto/block.c
index be823eebe..da60eba85 100644
--- a/crypto/block.c
+++ b/crypto/block.c
@@ -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,
diff --git a/crypto/blockpriv.h b/crypto/blockpriv.h
index 68f0f0670..62970859d 100644
--- a/crypto/blockpriv.h
+++ b/crypto/blockpriv.h
@@ -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
index 7690690f7..000000000
--- a/crypto/hash-gcrypt.c
+++ /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
index ec99ac9df..000000000
--- a/crypto/hash-glib.c
+++ /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
index 6a206dcb1..000000000
--- a/crypto/hash-nettle.c
+++ /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;
-}
diff --git a/crypto/hash.c b/crypto/hash.c
index 0f1ceac66..b90af3495 100644
--- a/crypto/hash.c
+++ b/crypto/hash.c
@@ -22,23 +22,126 @@
#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,
diff --git a/crypto/ivgenpriv.h b/crypto/ivgenpriv.h
index 28e5c6738..7b87e02ea 100644
--- a/crypto/ivgenpriv.h
+++ b/crypto/ivgenpriv.h
@@ -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__ */
diff --git a/crypto/pbkdf-gcrypt.c b/crypto/pbkdf-gcrypt.c
index 34af3a97e..997b311d8 100644
--- a/crypto/pbkdf-gcrypt.c
+++ b/crypto/pbkdf-gcrypt.c
@@ -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)
{
diff --git a/crypto/pbkdf-nettle.c b/crypto/pbkdf-nettle.c
index d681a606f..db9fc1578 100644
--- a/crypto/pbkdf-nettle.c
+++ b/crypto/pbkdf-nettle.c
@@ -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)
diff --git a/crypto/random-platform.c b/crypto/random-stub.c
index 82b755afa..63bbf4147 100644
--- a/crypto/random-platform.c
+++ b/crypto/random-stub.c
@@ -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;
}
diff --git a/crypto/tlscreds.c b/crypto/tlscreds.c
index a8965531b..1620e126a 100644
--- a/crypto/tlscreds.c
+++ b/crypto/tlscreds.c
@@ -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);
}
diff --git a/crypto/tlscredspriv.h b/crypto/tlscredspriv.h
index 13e9b6c0b..9222be4a9 100644
--- a/crypto/tlscredspriv.h
+++ b/crypto/tlscredspriv.h
@@ -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__ */
+
diff --git a/crypto/tlscredsx509.c b/crypto/tlscredsx509.c
index 520d34d77..6a0179c2e 100644
--- a/crypto/tlscredsx509.c
+++ b/crypto/tlscredsx509.c
@@ -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;
}
diff --git a/crypto/tlssession.c b/crypto/tlssession.c
index 2de42c61c..a543e5a57 100644
--- a/crypto/tlssession.c
+++ b/crypto/tlssession.c
@@ -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
index 818184372..000000000
--- a/crypto/trace-events
+++ /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"
diff --git a/default-configs/aarch64-softmmu.mak b/default-configs/aarch64-softmmu.mak
index 24494832c..96dd994b3 100644
--- a/default-configs/aarch64-softmmu.mak
+++ b/default-configs/aarch64-softmmu.mak
@@ -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
diff --git a/default-configs/arm-softmmu.mak b/default-configs/arm-softmmu.mak
index 7a19863b1..c63cdd073 100644
--- a/default-configs/arm-softmmu.mak
+++ b/default-configs/arm-softmmu.mak
@@ -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
diff --git a/default-configs/pci.mak b/default-configs/pci.mak
index fff7ce3b1..9c8bc68c4 100644
--- a/default-configs/pci.mak
+++ b/default-configs/pci.mak
@@ -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
diff --git a/default-configs/ppc64-softmmu.mak b/default-configs/ppc64-softmmu.mak
index c4be59f63..bb71b23ee 100644
--- a/default-configs/ppc64-softmmu.mak
+++ b/default-configs/ppc64-softmmu.mak
@@ -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
diff --git a/device_tree.c b/device_tree.c
index 6e0632083..ccba1fd4a 100644
--- a/device_tree.c
+++ b/device_tree.c
@@ -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"
diff --git a/disas/alpha.c b/disas/alpha.c
index b7b0ae0d9..44d00a363 100644
--- a/disas/alpha.c
+++ b/disas/alpha.c
@@ -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);
}
diff --git a/disas/arm.c b/disas/arm.c
index 426270fe8..70da5298a 100644
--- a/disas/arm.c
+++ b/disas/arm.c
@@ -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;
diff --git a/disas/i386.c b/disas/i386.c
index 57145d0a6..c0e717abe 100644
--- a/disas/i386.c
+++ b/disas/i386.c
@@ -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)
diff --git a/disas/m68k.c b/disas/m68k.c
index 8e7c3f76c..8f74ae115 100644
--- a/disas/m68k.c
+++ b/disas/m68k.c
@@ -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;
diff --git a/disas/mips.c b/disas/mips.c
index 97f661a37..249931b73 100644
--- a/disas/mips.c
+++ b/disas/mips.c
@@ -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
diff --git a/disas/ppc.c b/disas/ppc.c
index 052cebe85..478332ba3 100644
--- a/disas/ppc.c
+++ b/disas/ppc.c
@@ -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. */
diff --git a/disas/sparc.c b/disas/sparc.c
index f120f4e86..64bba8df2 100644
--- a/disas/sparc.c
+++ b/disas/sparc.c
@@ -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);
}
diff --git a/dma-helpers.c b/dma-helpers.c
index 9defc101b..4ad0bca67 100644
--- a/dma-helpers.c
+++ b/dma-helpers.c
@@ -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);
}
diff --git a/docs/atomics.txt b/docs/atomics.txt
index c95950b6c..ef285e3c2 100644
--- a/docs/atomics.txt
+++ b/docs/atomics.txt
@@ -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
diff --git a/docs/build-system.txt b/docs/build-system.txt
index 2af1e668c..5ddddeaaf 100644
--- a/docs/build-system.txt
+++ b/docs/build-system.txt
@@ -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
index e17bb5078..000000000
--- a/docs/igd-assign.txt
+++ /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
diff --git a/docs/memory.txt b/docs/memory.txt
index 811b1bd3c..431d9ca88 100644
--- a/docs/memory.txt
+++ b/docs/memory.txt
@@ -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,
diff --git a/docs/migration.txt b/docs/migration.txt
index 6503c1768..90209ab29 100644
--- a/docs/migration.txt
+++ b/docs/migration.txt
@@ -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)
diff --git a/docs/multi-thread-compression.txt b/docs/multi-thread-compression.txt
index d0caaf7b3..3d477c3bd 100644
--- a/docs/multi-thread-compression.txt
+++ b/docs/multi-thread-compression.txt
@@ -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:
diff --git a/docs/qapi-code-gen.txt b/docs/qapi-code-gen.txt
index de298dcae..0e4bafff0 100644
--- a/docs/qapi-code-gen.txt
+++ b/docs/qapi-code-gen.txt
@@ -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)
diff --git a/docs/qmp-events.txt b/docs/qmp-events.txt
index 7967ec4c5..fa7574d67 100644
--- a/docs/qmp-events.txt
+++ b/docs/qmp-events.txt
@@ -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.
diff --git a/docs/specs/acpi_cpu_hotplug.txt b/docs/specs/acpi_cpu_hotplug.txt
index ee219c835..340b751a9 100644
--- a/docs/specs/acpi_cpu_hotplug.txt
+++ b/docs/specs/acpi_cpu_hotplug.txt
@@ -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
index 0fdd251fc..000000000
--- a/docs/specs/acpi_nvdimm.txt
+++ /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)
diff --git a/docs/specs/parallels.txt b/docs/specs/parallels.txt
index e9271eba5..b4fe2295f 100644
--- a/docs/specs/parallels.txt
+++ b/docs/specs/parallels.txt
@@ -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
diff --git a/docs/specs/vhost-user.txt b/docs/specs/vhost-user.txt
index 7890d7169..777c49cfe 100644
--- a/docs/specs/vhost-user.txt
+++ b/docs/specs/vhost-user.txt
@@ -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.)
diff --git a/docs/throttle.txt b/docs/throttle.txt
index 26d4d5107..06ed9b394 100644
--- a/docs/throttle.txt
+++ b/docs/throttle.txt
@@ -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
diff --git a/docs/tracing.txt b/docs/tracing.txt
index 29f2f9a24..0bd6b9cf9 100644
--- a/docs/tracing.txt
+++ b/docs/tracing.txt
@@ -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
diff --git a/docs/usb-storage.txt b/docs/usb-storage.txt
index fbc1f2edd..c5a3866ee 100644
--- a/docs/usb-storage.txt
+++ b/docs/usb-storage.txt
@@ -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
diff --git a/docs/virtio-migration.txt b/docs/virtio-migration.txt
index 98a6b0ffb..cf66458b9 100644
--- a/docs/virtio-migration.txt
+++ b/docs/virtio-migration.txt
@@ -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 f7b80d856..9726f1f47 100644
--- 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 8ffde7598..fc7526666 100644
--- a/exec.c
+++ b/exec.c
@@ -19,30 +19,29 @@
#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);
diff --git a/fpu/softfloat-specialize.h b/fpu/softfloat-specialize.h
index f5aed72e8..a4cbdad45 100644
--- a/fpu/softfloat-specialize.h
+++ b/fpu/softfloat-specialize.h
@@ -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);
}
}
+
diff --git a/fpu/softfloat.c b/fpu/softfloat.c
index 9b1eccff2..166c48e43 100644
--- a/fpu/softfloat.c
+++ b/fpu/softfloat.c
@@ -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; \
} \
} \
diff --git a/fsdev/9p-iov-marshal.c b/fsdev/9p-iov-marshal.c
index 663cad542..fb40bdf0d 100644
--- a/fsdev/9p-iov-marshal.c
+++ b/fsdev/9p-iov-marshal.c
@@ -12,8 +12,10 @@
*/
#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;
diff --git a/fsdev/9p-iov-marshal.h b/fsdev/9p-iov-marshal.h
index 1fb501685..6bccbfb41 100644
--- a/fsdev/9p-iov-marshal.h
+++ b/fsdev/9p-iov-marshal.h
@@ -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"
diff --git a/fsdev/9p-marshal.c b/fsdev/9p-marshal.c
index 238dbf21b..183d3667c 100644
--- a/fsdev/9p-marshal.c
+++ b/fsdev/9p-marshal.c
@@ -12,9 +12,11 @@
*/
#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"
diff --git a/fsdev/9p-marshal.h b/fsdev/9p-marshal.h
index 140db6d99..e91b24e9c 100644
--- a/fsdev/9p-marshal.h
+++ b/fsdev/9p-marshal.h
@@ -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
{
diff --git a/fsdev/file-op-9p.h b/fsdev/file-op-9p.h
index 6db9feac8..b8c26024a 100644
--- a/fsdev/file-op-9p.h
+++ b/fsdev/file-op-9p.h
@@ -1,5 +1,5 @@
/*
- * 9p
+ * Virtio 9p
*
* Copyright IBM, Corp. 2010
*
@@ -10,12 +10,11 @@
* 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);
diff --git a/fsdev/qemu-fsdev-dummy.c b/fsdev/qemu-fsdev-dummy.c
index 6dc0fbc4c..7622e86c1 100644
--- a/fsdev/qemu-fsdev-dummy.c
+++ b/fsdev/qemu-fsdev-dummy.c
@@ -1,5 +1,5 @@
/*
- * 9p
+ * Virtio 9p
*
* Copyright IBM, Corp. 2010
*
diff --git a/fsdev/qemu-fsdev-opts.c b/fsdev/qemu-fsdev-opts.c
index 1dd8c7a24..88a4ac325 100644
--- a/fsdev/qemu-fsdev-opts.c
+++ b/fsdev/qemu-fsdev-opts.c
@@ -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.
diff --git a/fsdev/qemu-fsdev.c b/fsdev/qemu-fsdev.c
index 266e442b8..bf7f0b07f 100644
--- a/fsdev/qemu-fsdev.c
+++ b/fsdev/qemu-fsdev.c
@@ -1,5 +1,5 @@
/*
- * 9p
+ * Virtio 9p
*
* Copyright IBM, Corp. 2010
*
diff --git a/fsdev/qemu-fsdev.h b/fsdev/qemu-fsdev.h
index 29c962296..9fa45bf51 100644
--- a/fsdev/qemu-fsdev.h
+++ b/fsdev/qemu-fsdev.h
@@ -1,5 +1,5 @@
/*
- * 9p
+ * Virtio 9p
*
* Copyright IBM, Corp. 2010
*
diff --git a/fsdev/virtfs-proxy-helper.texi b/fsdev/virtfs-proxy-helper.texi
index f4cbb6062..6eb2d5096 100644
--- a/fsdev/virtfs-proxy-helper.texi
+++ b/fsdev/virtfs-proxy-helper.texi
@@ -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
diff --git a/gdbstub.c b/gdbstub.c
index 5da66f179..0e431fd4d 100644
--- 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);
diff --git a/hmp-commands-info.hx b/hmp-commands-info.hx
index 74446c669..52539c310 100644
--- a/hmp-commands-info.hx
+++ b/hmp-commands-info.hx
@@ -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
diff --git a/hmp-commands.hx b/hmp-commands.hx
index 848efee5d..4f4f60a0d 100644
--- a/hmp-commands.hx
+++ b/hmp-commands.hx
@@ -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 cc2056e9e..d51023667 100644
--- 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 0876ec03a..093d65f5a 100644
--- 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
diff --git a/hw/9pfs/9p-handle.c b/hw/9pfs/9p-handle.c
index 3d77594f9..894041488 100644
--- a/hw/9pfs/9p-handle.c
+++ b/hw/9pfs/9p-handle.c
@@ -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,
diff --git a/hw/9pfs/9p-local.c b/hw/9pfs/9p-local.c
index 3f271fcbd..16f45f485 100644
--- a/hw/9pfs/9p-local.c
+++ b/hw/9pfs/9p-local.c
@@ -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,
diff --git a/hw/9pfs/9p-proxy.c b/hw/9pfs/9p-proxy.c
index f265501ea..00a4eb2a7 100644
--- a/hw/9pfs/9p-proxy.c
+++ b/hw/9pfs/9p-proxy.c
@@ -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,
diff --git a/hw/9pfs/9p-proxy.h b/hw/9pfs/9p-proxy.h
index b84301d00..ba9ca203d 100644
--- a/hw/9pfs/9p-proxy.h
+++ b/hw/9pfs/9p-proxy.h
@@ -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
diff --git a/hw/9pfs/9p-synth.c b/hw/9pfs/9p-synth.c
index 4b6d4e6a3..f1475dfd6 100644
--- a/hw/9pfs/9p-synth.c
+++ b/hw/9pfs/9p-synth.c
@@ -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"
@@ -21,19 +23,19 @@
#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,
};
diff --git a/hw/9pfs/9p-synth.h b/hw/9pfs/9p-synth.h
index 6bcb44ace..82962512a 100644
--- a/hw/9pfs/9p-synth.h
+++ b/hw/9pfs/9p-synth.h
@@ -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,
diff --git a/hw/9pfs/9p-xattr.h b/hw/9pfs/9p-xattr.h
index a853ea641..4d39a2026 100644
--- a/hw/9pfs/9p-xattr.h
+++ b/hw/9pfs/9p-xattr.h
@@ -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"
diff --git a/hw/9pfs/9p.c b/hw/9pfs/9p.c
index dfe293d11..f5e30125f 100644
--- a/hw/9pfs/9p.c
+++ b/hw/9pfs/9p.c
@@ -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. */
diff --git a/hw/9pfs/9p.h b/hw/9pfs/9p.h
index a38603398..1a19418a8 100644
--- a/hw/9pfs/9p.h
+++ b/hw/9pfs/9p.h
@@ -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 */
diff --git a/hw/9pfs/codir.c b/hw/9pfs/codir.c
index d91f9ad6e..91df7f7a7 100644
--- a/hw/9pfs/codir.c
+++ b/hw/9pfs/codir.c
@@ -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;
}
});
diff --git a/hw/9pfs/cofile.c b/hw/9pfs/cofile.c
index 10343c0a9..293483e0c 100644
--- a/hw/9pfs/cofile.c
+++ b/hw/9pfs/cofile.c
@@ -1,5 +1,6 @@
+
/*
- * 9p backend
+ * Virtio 9p backend
*
* Copyright IBM, Corp. 2011
*
diff --git a/hw/9pfs/cofs.c b/hw/9pfs/cofs.c
index 70f584fcb..18c81cb3d 100644
--- a/hw/9pfs/cofs.c
+++ b/hw/9pfs/cofs.c
@@ -1,5 +1,6 @@
+
/*
- * 9p backend
+ * Virtio 9p backend
*
* Copyright IBM, Corp. 2011
*
diff --git a/hw/9pfs/coth.c b/hw/9pfs/coth.c
index 89018de6b..464293ef2 100644
--- a/hw/9pfs/coth.c
+++ b/hw/9pfs/coth.c
@@ -16,20 +16,21 @@
#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;
}
diff --git a/hw/9pfs/coth.h b/hw/9pfs/coth.h
index 3c7424e42..209fc6a9a 100644
--- a/hw/9pfs/coth.h
+++ b/hw/9pfs/coth.h
@@ -12,13 +12,12 @@
*
*/
-#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
@@ -48,8 +47,10 @@
} 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 *);
diff --git a/hw/9pfs/coxattr.c b/hw/9pfs/coxattr.c
index 133c4ead3..6ad96ea9f 100644
--- a/hw/9pfs/coxattr.c
+++ b/hw/9pfs/coxattr.c
@@ -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
index 48d3d8abe..000000000
--- a/hw/9pfs/trace-events
+++ /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"
diff --git a/hw/9pfs/virtio-9p-device.c b/hw/9pfs/virtio-9p-device.c
index 009b43f6d..a38850ee8 100644
--- a/hw/9pfs/virtio-9p-device.c
+++ b/hw/9pfs/virtio-9p-device.c
@@ -13,9 +13,11 @@
#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;
diff --git a/hw/9pfs/virtio-9p.h b/hw/9pfs/virtio-9p.h
index 7586b792d..7f6d88553 100644
--- a/hw/9pfs/virtio-9p.h
+++ b/hw/9pfs/virtio-9p.h
@@ -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"
diff --git a/hw/acpi/Makefile.objs b/hw/acpi/Makefile.objs
index 4b7da6639..faee86c5c 100644
--- a/hw/acpi/Makefile.objs
+++ b/hw/acpi/Makefile.objs
@@ -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
diff --git a/hw/acpi/acpi_interface.c b/hw/acpi/acpi_interface.c
index 6583917b8..d82131326 100644
--- a/hw/acpi/acpi_interface.c
+++ b/hw/acpi/acpi_interface.c
@@ -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 = {
diff --git a/hw/acpi/aml-build.c b/hw/acpi/aml-build.c
index db3e914fb..ab89ca638 100644
--- a/hw/acpi/aml-build.c
+++ b/hw/acpi/aml-build.c
@@ -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);
-}
diff --git a/hw/acpi/bios-linker-loader.c b/hw/acpi/bios-linker-loader.c
index d963ebe24..5153ab151 100644
--- a/hw/acpi/bios-linker-loader.c
+++ b/hw/acpi/bios-linker-loader.c
@@ -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);
}
diff --git a/hw/acpi/core.c b/hw/acpi/core.c
index e890a5d67..6a2f45214 100644
--- a/hw/acpi/core.c
+++ b/hw/acpi/core.c
@@ -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
index c13b65c2c..000000000
--- a/hw/acpi/cpu.c
+++ /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);
-}
diff --git a/hw/acpi/cpu_hotplug.c b/hw/acpi/cpu_hotplug.c
index e19d90206..4d86743fd 100644
--- a/hw/acpi/cpu_hotplug.c
+++ b/hw/acpi/cpu_hotplug.c
@@ -14,14 +14,6 @@
#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
index 000000000..97bb1092a
--- /dev/null
+++ b/hw/acpi/cpu_hotplug_acpi_table.c
@@ -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);
+}
diff --git a/hw/acpi/ich9.c b/hw/acpi/ich9.c
index e5a3c18e5..27e978f5f 100644
--- a/hw/acpi/ich9.c
+++ b/hw/acpi/ich9.c
@@ -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
index 7e74ce446..000000000
--- a/hw/acpi/ipmi.c
+++ /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));
- }
-}
diff --git a/hw/acpi/memory_hotplug.c b/hw/acpi/memory_hotplug.c
index ec4e64b36..f65a3a21e 100644
--- a/hw/acpi/memory_hotplug.c
+++ b/hw/acpi/memory_hotplug.c
@@ -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,
diff --git a/hw/acpi/nvdimm.c b/hw/acpi/nvdimm.c
index e486128aa..9531340e5 100644
--- a/hw/acpi/nvdimm.c
+++ b/hw/acpi/nvdimm.c
@@ -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);
}
diff --git a/hw/acpi/pcihp.c b/hw/acpi/pcihp.c
index d957d1e30..71f4c4e14 100644
--- a/hw/acpi/pcihp.c
+++ b/hw/acpi/pcihp.c
@@ -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)
diff --git a/hw/acpi/piix4.c b/hw/acpi/piix4.c
index 2adc246b0..16abdf162 100644
--- a/hw/acpi/piix4.c
+++ b/hw/acpi/piix4.c
@@ -34,13 +34,11 @@
#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
index c379607a3..000000000
--- a/hw/acpi/trace-events
+++ /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
diff --git a/hw/alpha/alpha_sys.h b/hw/alpha/alpha_sys.h
index ed911f22a..e11025b4b 100644
--- a/hw/alpha/alpha_sys.h
+++ b/hw/alpha/alpha_sys.h
@@ -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"
diff --git a/hw/alpha/pci.c b/hw/alpha/pci.c
index 8dde637bf..5baa0eaf1 100644
--- a/hw/alpha/pci.c
+++ b/hw/alpha/pci.c
@@ -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
index e44ff01a0..000000000
--- a/hw/alpha/trace-events
+++ /dev/null
@@ -1,4 +0,0 @@
-# See docs/tracing.txt for syntax documentation.
-
-# hw/alpha/pci.c
-alpha_pci_iack_write(void) ""
diff --git a/hw/alpha/typhoon.c b/hw/alpha/typhoon.c
index 883db13f9..97721b535 100644
--- a/hw/alpha/typhoon.c
+++ b/hw/alpha/typhoon.c
@@ -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,
diff --git a/hw/arm/Makefile.objs b/hw/arm/Makefile.objs
index 12764ef2b..954c9fe15 100644
--- a/hw/arm/Makefile.objs
+++ b/hw/arm/Makefile.objs
@@ -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
diff --git a/hw/arm/armv7m.c b/hw/arm/armv7m.c
index 49d30782c..bb2a22d96 100644
--- a/hw/arm/armv7m.c
+++ b/hw/arm/armv7m.c
@@ -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,
};
diff --git a/hw/arm/ast2400.c b/hw/arm/ast2400.c
index 326fdb36e..03f993863 100644
--- a/hw/arm/ast2400.c
+++ b/hw/arm/ast2400.c
@@ -17,22 +17,12 @@
#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)
diff --git a/hw/arm/bcm2835_peripherals.c b/hw/arm/bcm2835_peripherals.c
index 2e641a398..234d51843 100644
--- a/hw/arm/bcm2835_peripherals.c
+++ b/hw/arm/bcm2835_peripherals.c
@@ -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 = {
diff --git a/hw/arm/boot.c b/hw/arm/boot.c
index 1b913a43c..587694557 100644
--- a/hw/arm/boot.c
+++ b/hw/arm/boot.c
@@ -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) {
diff --git a/hw/arm/collie.c b/hw/arm/collie.c
index 2e6953128..8bb308a42 100644
--- a/hw/arm/collie.c
+++ b/hw/arm/collie.c
@@ -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,
diff --git a/hw/arm/digic.c b/hw/arm/digic.c
index d60ea395f..e0f973032 100644
--- a/hw/arm/digic.c
+++ b/hw/arm/digic.c
@@ -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);
diff --git a/hw/arm/fsl-imx25.c b/hw/arm/fsl-imx25.c
index b4e358db6..2f878b935 100644
--- a/hw/arm/fsl-imx25.c
+++ b/hw/arm/fsl-imx25.c
@@ -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;
diff --git a/hw/arm/fsl-imx31.c b/hw/arm/fsl-imx31.c
index fe204ace6..31a3a8791 100644
--- a/hw/arm/fsl-imx31.c
+++ b/hw/arm/fsl-imx31.c
@@ -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
index 6a1bf263a..000000000
--- a/hw/arm/fsl-imx6.c
+++ /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)
diff --git a/hw/arm/highbank.c b/hw/arm/highbank.c
index 80e5fd458..d9930c0d3 100644
--- a/hw/arm/highbank.c
+++ b/hw/arm/highbank.c
@@ -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);
diff --git a/hw/arm/integratorcp.c b/hw/arm/integratorcp.c
index 96dc15002..e31bca6e7 100644
--- a/hw/arm/integratorcp.c
+++ b/hw/arm/integratorcp.c
@@ -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 = {
diff --git a/hw/arm/musicpal.c b/hw/arm/musicpal.c
index cc50ace13..7a4cc07dd 100644
--- a/hw/arm/musicpal.c
+++ b/hw/arm/musicpal.c
@@ -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,
diff --git a/hw/arm/nseries.c b/hw/arm/nseries.c
index fea911e3e..538250555 100644
--- a/hw/arm/nseries.c
+++ b/hw/arm/nseries.c
@@ -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);
}
}
diff --git a/hw/arm/palmetto-bmc.c b/hw/arm/palmetto-bmc.c
index 54e29a865..89ebd92b9 100644
--- a/hw/arm/palmetto-bmc.c
+++ b/hw/arm/palmetto-bmc.c
@@ -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;
diff --git a/hw/arm/pxa2xx.c b/hw/arm/pxa2xx.c
index cb5570468..1a8c36033 100644
--- a/hw/arm/pxa2xx.c
+++ b/hw/arm/pxa2xx.c
@@ -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);
diff --git a/hw/arm/pxa2xx_gpio.c b/hw/arm/pxa2xx_gpio.c
index 576a8eb91..67e7e7094 100644
--- a/hw/arm/pxa2xx_gpio.c
+++ b/hw/arm/pxa2xx_gpio.c
@@ -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
diff --git a/hw/arm/pxa2xx_pic.c b/hw/arm/pxa2xx_pic.c
index b516ced8c..7e51532cd 100644
--- a/hw/arm/pxa2xx_pic.c
+++ b/hw/arm/pxa2xx_pic.c
@@ -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;
}
diff --git a/hw/arm/realview.c b/hw/arm/realview.c
index 8eafccaf1..3222b360e 100644
--- a/hw/arm/realview.c
+++ b/hw/arm/realview.c
@@ -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
index 4e7ac8cc4..000000000
--- a/hw/arm/sabrelite.c
+++ /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)
diff --git a/hw/arm/spitz.c b/hw/arm/spitz.c
index 41cc2eeeb..bf61d63b5 100644
--- a/hw/arm/spitz.c
+++ b/hw/arm/spitz.c
@@ -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;
}
diff --git a/hw/arm/stellaris.c b/hw/arm/stellaris.c
index 794a3ada7..c1766f856 100644
--- a/hw/arm/stellaris.c
+++ b/hw/arm/stellaris.c
@@ -17,10 +17,8 @@
#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,
};
diff --git a/hw/arm/stm32f205_soc.c b/hw/arm/stm32f205_soc.c
index de26b8caf..a5ea1e237 100644
--- a/hw/arm/stm32f205_soc.c
+++ b/hw/arm/stm32f205_soc.c
@@ -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);
diff --git a/hw/arm/strongarm.c b/hw/arm/strongarm.c
index f1b2c6c96..1eeb1ab39 100644
--- a/hw/arm/strongarm.c
+++ b/hw/arm/strongarm.c
@@ -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,
};
diff --git a/hw/arm/strongarm.h b/hw/arm/strongarm.h
index 1470eac4f..2893f9444 100644
--- a/hw/arm/strongarm.h
+++ b/hw/arm/strongarm.h
@@ -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
diff --git a/hw/arm/tosa.c b/hw/arm/tosa.c
index 2db66508b..4e9494f94 100644
--- a/hw/arm/tosa.c
+++ b/hw/arm/tosa.c
@@ -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
index d5f33a2a0..000000000
--- a/hw/arm/trace-events
+++ /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."
diff --git a/hw/arm/versatilepb.c b/hw/arm/versatilepb.c
index 8ae5392bc..e5a80c2d2 100644
--- a/hw/arm/versatilepb.c
+++ b/hw/arm/versatilepb.c
@@ -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,
};
diff --git a/hw/arm/vexpress.c b/hw/arm/vexpress.c
index 58760f40c..70b3e701e 100644
--- a/hw/arm/vexpress.c
+++ b/hw/arm/vexpress.c
@@ -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]);
diff --git a/hw/arm/virt-acpi-build.c b/hw/arm/virt-acpi-build.c
index 28fc59c66..f51fe396c 100644
--- a/hw/arm/virt-acpi-build.c
+++ b/hw/arm/virt-acpi-build.c
@@ -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));
diff --git a/hw/arm/virt.c b/hw/arm/virt.c
index a193b5a95..a535285e4 100644
--- a/hw/arm/virt.c
+++ b/hw/arm/virt.c
@@ -38,11 +38,9 @@
#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);
diff --git a/hw/arm/xilinx_zynq.c b/hw/arm/xilinx_zynq.c
index 7dac20d67..98b17c9ae 100644
--- a/hw/arm/xilinx_zynq.c
+++ b/hw/arm/xilinx_zynq.c
@@ -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;
diff --git a/hw/arm/xlnx-ep108.c b/hw/arm/xlnx-ep108.c
index 4ec590a25..5f480182b 100644
--- a/hw/arm/xlnx-ep108.c
+++ b/hw/arm/xlnx-ep108.c
@@ -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)
diff --git a/hw/arm/xlnx-zynqmp.c b/hw/arm/xlnx-zynqmp.c
index 23c719986..4d504da64 100644
--- a/hw/arm/xlnx-zynqmp.c
+++ b/hw/arm/xlnx-zynqmp.c
@@ -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
@@ -38,12 +36,6 @@
#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()
};
diff --git a/hw/arm/z2.c b/hw/arm/z2.c
index 68a92f318..aea895a50 100644
--- a/hw/arm/z2.c
+++ b/hw/arm/z2.c
@@ -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;
}
diff --git a/hw/audio/cs4231.c b/hw/audio/cs4231.c
index 30690f96a..caf97c169 100644
--- a/hw/audio/cs4231.c
+++ b/hw/audio/cs4231.c
@@ -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,
};
diff --git a/hw/audio/fmopl.h b/hw/audio/fmopl.h
index fdda7f9f5..24ba5f480 100644
--- a/hw/audio/fmopl.h
+++ b/hw/audio/fmopl.h
@@ -1,5 +1,5 @@
-#ifndef FMOPL_H
-#define FMOPL_H
+#ifndef __FMOPL_H_
+#define __FMOPL_H_
/* --- select emulation chips --- */
#define BUILD_YM3812 (HAS_YM3812)
diff --git a/hw/audio/gus.c b/hw/audio/gus.c
index 6c0264677..9dd6947be 100644
--- a/hw/audio/gus.c
+++ b/hw/audio/gus.c
@@ -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)
diff --git a/hw/audio/gusemu.h b/hw/audio/gusemu.h
index 9aec7bf8e..b7f075126 100644
--- a/hw/audio/gusemu.h
+++ b/hw/audio/gusemu.h
@@ -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 */
diff --git a/hw/audio/gustate.h b/hw/audio/gustate.h
index d16297110..ece903abb 100644
--- a/hw/audio/gustate.h
+++ b/hw/audio/gustate.h
@@ -129,4 +129,4 @@
#define gusdataend (VSRegsEnd+4)
-#endif /* GUSTATE_H */
+#endif /* gustate.h */
diff --git a/hw/audio/intel-hda.c b/hw/audio/intel-hda.c
index cd95340cd..d372d4ab9 100644
--- a/hw/audio/intel-hda.c
+++ b/hw/audio/intel-hda.c
@@ -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;
diff --git a/hw/audio/lm4549.h b/hw/audio/lm4549.h
index 74c3ee893..812a7a444 100644
--- a/hw/audio/lm4549.h
+++ b/hw/audio/lm4549.h
@@ -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 */
diff --git a/hw/audio/milkymist-ac97.c b/hw/audio/milkymist-ac97.c
index bc8db71ae..6a3b53674 100644
--- a/hw/audio/milkymist-ac97.c
+++ b/hw/audio/milkymist-ac97.c
@@ -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,
};
diff --git a/hw/audio/pcspk.c b/hw/audio/pcspk.c
index 42a6f4885..f9afc8eda 100644
--- a/hw/audio/pcspk.c
+++ b/hw/audio/pcspk.c
@@ -31,12 +31,11 @@
#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;
}
diff --git a/hw/audio/pl041.c b/hw/audio/pl041.c
index 6e9c10401..4717bc9b9 100644
--- a/hw/audio/pl041.c
+++ b/hw/audio/pl041.c
@@ -22,7 +22,6 @@
#include "qemu/osdep.h"
#include "hw/sysbus.h"
-#include "qemu/log.h"
#include "pl041.h"
#include "lm4549.h"
diff --git a/hw/audio/pl041.h b/hw/audio/pl041.h
index 515db4756..427ab6d6f 100644
--- a/hw/audio/pl041.h
+++ b/hw/audio/pl041.h
@@ -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
index 3210386e8..000000000
--- a/hw/audio/trace-events
+++ /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"
diff --git a/hw/block/block.c b/hw/block/block.c
index 8dc9d84a3..97a59d4fa 100644
--- a/hw/block/block.c
+++ b/hw/block/block.c
@@ -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)
diff --git a/hw/block/dataplane/virtio-blk.c b/hw/block/dataplane/virtio-blk.c
index 704a76360..3cb97c9a2 100644
--- a/hw/block/dataplane/virtio-blk.c
+++ b/hw/block/dataplane/virtio-blk.c
@@ -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;
diff --git a/hw/block/dataplane/virtio-blk.h b/hw/block/dataplane/virtio-blk.h
index b1f0b95b3..0714c11a2 100644
--- a/hw/block/dataplane/virtio-blk.h
+++ b/hw/block/dataplane/virtio-blk.h
@@ -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 */
diff --git a/hw/block/fdc.c b/hw/block/fdc.c
index f73af7db4..372227569 100644
--- a/hw/block/fdc.c
+++ b/hw/block/fdc.c
@@ -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;
diff --git a/hw/block/hd-geometry.c b/hw/block/hd-geometry.c
index 57ad5012a..6d02192db 100644
--- a/hw/block/hd-geometry.c
+++ b/hw/block/hd-geometry.c
@@ -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 */
diff --git a/hw/block/m25p80.c b/hw/block/m25p80.c
index 9828ee61d..906b71257 100644
--- a/hw/block/m25p80.c
+++ b/hw/block/m25p80.c
@@ -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
@@ -54,17 +52,12 @@
/* 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;
diff --git a/hw/block/nand.c b/hw/block/nand.c
index c69e6755d..29c659681 100644
--- a/hw/block/nand.c
+++ b/hw/block/nand.c
@@ -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);
}
diff --git a/hw/block/nvme.c b/hw/block/nvme.c
index cef3bb42f..173988ee8 100644
--- a/hw/block/nvme.c
+++ b/hw/block/nvme.c
@@ -21,10 +21,10 @@
*/
#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);
diff --git a/hw/block/onenand.c b/hw/block/onenand.c
index 8d8422739..883f4b1fa 100644
--- a/hw/block/onenand.c
+++ b/hw/block/onenand.c
@@ -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 {
diff --git a/hw/block/pflash_cfi01.c b/hw/block/pflash_cfi01.c
index 62d7a5661..106a77523 100644
--- a/hw/block/pflash_cfi01.c
+++ b/hw/block/pflash_cfi01.c
@@ -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));
diff --git a/hw/block/pflash_cfi02.c b/hw/block/pflash_cfi02.c
index 4f6105cc5..b13172c6e 100644
--- a/hw/block/pflash_cfi02.c
+++ b/hw/block/pflash_cfi02.c
@@ -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");
diff --git a/hw/block/tc58128.c b/hw/block/tc58128.c
index 1d9f7ee00..7909d5041 100644
--- a/hw/block/tc58128.c
+++ b/hw/block/tc58128.c
@@ -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
index d0dd94ff0..000000000
--- a/hw/block/trace-events
+++ /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"
diff --git a/hw/block/virtio-blk.c b/hw/block/virtio-blk.c
index 331d7667e..3f88f8cf5 100644
--- a/hw/block/virtio-blk.c
+++ b/hw/block/virtio-blk.c
@@ -29,11 +29,9 @@
#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;
diff --git a/hw/block/xen_blkif.h b/hw/block/xen_blkif.h
index 3300b6fc0..c68487cb3 100644
--- a/hw/block/xen_blkif.h
+++ b/hw/block/xen_blkif.h
@@ -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__ */
diff --git a/hw/block/xen_disk.c b/hw/block/xen_disk.c
index 3b8ad33fc..d4ce380fe 100644
--- a/hw/block/xen_disk.c
+++ b/hw/block/xen_disk.c
@@ -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;
}
diff --git a/hw/bt/hci-csr.c b/hw/bt/hci-csr.c
index d688372ca..2e970b656 100644
--- a/hw/bt/hci-csr.c
+++ b/hw/bt/hci-csr.c
@@ -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) */
diff --git a/hw/bt/hci.c b/hw/bt/hci.c
index 351123fab..7d5220509 100644
--- a/hw/bt/hci.c
+++ b/hw/bt/hci.c
@@ -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! */
diff --git a/hw/bt/l2cap.c b/hw/bt/l2cap.c
index e34204514..806525194 100644
--- a/hw/bt/l2cap.c
+++ b/hw/bt/l2cap.c
@@ -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;
diff --git a/hw/bt/sdp.c b/hw/bt/sdp.c
index f67b3b89c..be26009b0 100644
--- a/hw/bt/sdp.c
+++ b/hw/bt/sdp.c
@@ -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 {
diff --git a/hw/char/bcm2835_aux.c b/hw/char/bcm2835_aux.c
index 319f1652f..0394d11a8 100644
--- a/hw/char/bcm2835_aux.c
+++ b/hw/char/bcm2835_aux.c
@@ -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
diff --git a/hw/char/cadence_uart.c b/hw/char/cadence_uart.c
index e3bc52f7d..797787823 100644
--- a/hw/char/cadence_uart.c
+++ b/hw/char/cadence_uart.c
@@ -17,10 +17,6 @@
*/
#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,
diff --git a/hw/char/digic-uart.c b/hw/char/digic-uart.c
index c7604e676..d3bc533d7 100644
--- a/hw/char/digic-uart.c
+++ b/hw/char/digic-uart.c
@@ -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 = {
diff --git a/hw/char/escc.c b/hw/char/escc.c
index 31a5f902f..7bf09a007 100644
--- a/hw/char/escc.c
+++ b/hw/char/escc.c
@@ -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,
};
diff --git a/hw/char/etraxfs_ser.c b/hw/char/etraxfs_ser.c
index 04ca04fe2..146b387e7 100644
--- a/hw/char/etraxfs_ser.c
+++ b/hw/char/etraxfs_ser.c
@@ -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,
};
diff --git a/hw/char/imx_serial.c b/hw/char/imx_serial.c
index 44856d671..6df74ac7c 100644
--- a/hw/char/imx_serial.c
+++ b/hw/char/imx_serial.c
@@ -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
diff --git a/hw/char/ipoctal232.c b/hw/char/ipoctal232.c
index 9ead32af6..bc0ae4980 100644
--- a/hw/char/ipoctal232.c
+++ b/hw/char/ipoctal232.c
@@ -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.
diff --git a/hw/char/lm32_juart.c b/hw/char/lm32_juart.c
index 28c2cf702..5bf8acfe8 100644
--- a/hw/char/lm32_juart.c
+++ b/hw/char/lm32_juart.c
@@ -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 = {
diff --git a/hw/char/lm32_uart.c b/hw/char/lm32_uart.c
index b5c760dda..036813d0f 100644
--- a/hw/char/lm32_uart.c
+++ b/hw/char/lm32_uart.c
@@ -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,
};
diff --git a/hw/char/milkymist-uart.c b/hw/char/milkymist-uart.c
index baddb3764..03b36b223 100644
--- a/hw/char/milkymist-uart.c
+++ b/hw/char/milkymist-uart.c
@@ -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 = {
diff --git a/hw/char/pl011.c b/hw/char/pl011.c
index c0fbf8a87..210c87b4c 100644
--- a/hw/char/pl011.c
+++ b/hw/char/pl011.c
@@ -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 = {
diff --git a/hw/char/sclpconsole-lm.c b/hw/char/sclpconsole-lm.c
index a22ad8d01..7d4ff8120 100644
--- a/hw/char/sclpconsole-lm.c
+++ b/hw/char/sclpconsole-lm.c
@@ -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;
diff --git a/hw/char/sclpconsole.c b/hw/char/sclpconsole.c
index d22464826..45997ff4a 100644
--- a/hw/char/sclpconsole.c
+++ b/hw/char/sclpconsole.c
@@ -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;
diff --git a/hw/char/serial.c b/hw/char/serial.c
index 3442f47d3..6d815b5c6 100644
--- a/hw/char/serial.c
+++ b/hw/char/serial.c
@@ -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;
diff --git a/hw/char/stm32f2xx_usart.c b/hw/char/stm32f2xx_usart.c
index 15657abda..a94d61ceb 100644
--- a/hw/char/stm32f2xx_usart.c
+++ b/hw/char/stm32f2xx_usart.c
@@ -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
index d53577c99..000000000
--- a/hw/char/trace-events
+++ /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"
diff --git a/hw/char/virtio-console.c b/hw/char/virtio-console.c
index 4f0e03d3b..2e36481a7 100644
--- a/hw/char/virtio-console.c
+++ b/hw/char/virtio-console.c
@@ -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);
}
}
diff --git a/hw/char/virtio-serial-bus.c b/hw/char/virtio-serial-bus.c
index db57a3854..6e5de6dec 100644
--- a/hw/char/virtio-serial-bus.c
+++ b/hw/char/virtio-serial-bus.c
@@ -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;
diff --git a/hw/char/xen_console.c b/hw/char/xen_console.c
index 83108b0bd..cbf1dccbb 100644
--- a/hw/char/xen_console.c
+++ b/hw/char/xen_console.c
@@ -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"
diff --git a/hw/char/xilinx_uartlite.c b/hw/char/xilinx_uartlite.c
index 4847efb29..911af4a0d 100644
--- a/hw/char/xilinx_uartlite.c
+++ b/hw/char/xilinx_uartlite.c
@@ -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 = {
diff --git a/hw/core/Makefile.objs b/hw/core/Makefile.objs
index cfd484039..abb3560be 100644
--- a/hw/core/Makefile.objs
+++ b/hw/core/Makefile.objs
@@ -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
index 3e3f8ac74..000000000
--- a/hw/core/bus.c
+++ /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)
diff --git a/hw/core/hotplug.c b/hw/core/hotplug.c
index 17ac98668..645cfca1b 100644
--- a/hw/core/hotplug.c
+++ b/hw/core/hotplug.c
@@ -13,17 +13,6 @@
#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)
diff --git a/hw/core/loader.c b/hw/core/loader.c
index 53e0e4155..c0499571c 100644
--- a/hw/core/loader.c
+++ b/hw/core/loader.c
@@ -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;
}
diff --git a/hw/core/machine.c b/hw/core/machine.c
index e5a456f21..6dbbc85b9 100644
--- a/hw/core/machine.c
+++ b/hw/core/machine.c
@@ -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,
diff --git a/hw/core/nmi.c b/hw/core/nmi.c
index bfd0896da..e8bcc4177 100644
--- a/hw/core/nmi.c
+++ b/hw/core/nmi.c
@@ -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,
diff --git a/hw/core/ptimer.c b/hw/core/ptimer.c
index 30829ee97..153c83513 100644
--- a/hw/core/ptimer.c
+++ b/hw/core/ptimer.c
@@ -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,
diff --git a/hw/core/qdev-properties-system.c b/hw/core/qdev-properties-system.c
index e55afe6bf..891219ae0 100644
--- a/hw/core/qdev-properties-system.c
+++ b/hw/core/qdev-properties-system.c
@@ -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);
+}
diff --git a/hw/core/qdev-properties.c b/hw/core/qdev-properties.c
index 311af6da7..737d29c63 100644
--- a/hw/core/qdev-properties.c
+++ b/hw/core/qdev-properties.c
@@ -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;
}
}
}
diff --git a/hw/core/qdev.c b/hw/core/qdev.c
index 57834423b..db41aa1f2 100644
--- a/hw/core/qdev.c
+++ b/hw/core/qdev.c
@@ -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
index 4bfbc508d..000000000
--- a/hw/core/register.c
+++ /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)
diff --git a/hw/core/sysbus.c b/hw/core/sysbus.c
index c0f560b28..a7dbe2b32 100644
--- a/hw/core/sysbus.c
+++ b/hw/core/sysbus.c
@@ -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);
diff --git a/hw/core/uboot_image.h b/hw/core/uboot_image.h
index 34c11a70a..9fc2760b5 100644
--- a/hw/core/uboot_image.h
+++ b/hw/core/uboot_image.h
@@ -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__ */
diff --git a/hw/cpu/Makefile.objs b/hw/cpu/Makefile.objs
index 942a4bb82..0954a1872 100644
--- a/hw/cpu/Makefile.objs
+++ b/hw/cpu/Makefile.objs
@@ -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
diff --git a/hw/cpu/a9mpcore.c b/hw/cpu/a9mpcore.c
index f17f29209..5459ae8c1 100644
--- a/hw/cpu/a9mpcore.c
+++ b/hw/cpu/a9mpcore.c
@@ -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
index eff90c12b..000000000
--- a/hw/cpu/core.c
+++ /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)
diff --git a/hw/cris/axis_dev88.c b/hw/cris/axis_dev88.c
index 60df8877c..9f5865874 100644
--- a/hw/cris/axis_dev88.c
+++ b/hw/cris/axis_dev88.c
@@ -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) {
diff --git a/hw/cris/boot.h b/hw/cris/boot.h
index 218854e5d..c4d3fa6f6 100644
--- a/hw/cris/boot.h
+++ b/hw/cris/boot.h
@@ -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
{
diff --git a/hw/display/Makefile.objs b/hw/display/Makefile.objs
index 063889bea..d99780eeb 100644
--- a/hw/display/Makefile.objs
+++ b/hw/display/Makefile.objs
@@ -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
diff --git a/hw/display/ads7846.c b/hw/display/ads7846.c
index 166edade7..05aa2d1e6 100644
--- a/hw/display/ads7846.c
+++ b/hw/display/ads7846.c
@@ -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;
}
diff --git a/hw/display/bcm2835_fb.c b/hw/display/bcm2835_fb.c
index 7eab92765..506f1d3d9 100644
--- a/hw/display/bcm2835_fb.c
+++ b/hw/display/bcm2835_fb.c
@@ -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
diff --git a/hw/display/blizzard.c b/hw/display/blizzard.c
index cbf07d14d..c231960d9 100644
--- a/hw/display/blizzard.c
+++ b/hw/display/blizzard.c
@@ -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
index 000000000..b7ef27c80
--- /dev/null
+++ b/hw/display/blizzard_template.h
@@ -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
diff --git a/hw/display/cg3.c b/hw/display/cg3.c
index 117422039..fc0d97fa4 100644
--- a/hw/display/cg3.c
+++ b/hw/display/cg3.c
@@ -26,12 +26,10 @@
#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
index ce92ff6e2..000000000
--- a/hw/display/dpcd.c
+++ /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)
diff --git a/hw/display/exynos4210_fimd.c b/hw/display/exynos4210_fimd.c
index e5be71340..728eb214a 100644
--- a/hw/display/exynos4210_fimd.c
+++ b/hw/display/exynos4210_fimd.c
@@ -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,
};
diff --git a/hw/display/jazz_led.c b/hw/display/jazz_led.c
index b72fdb171..09dcdb46a 100644
--- a/hw/display/jazz_led.c
+++ b/hw/display/jazz_led.c
@@ -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,
};
diff --git a/hw/display/milkymist-tmu2.c b/hw/display/milkymist-tmu2.c
index 9c0018448..9bc88f93b 100644
--- a/hw/display/milkymist-tmu2.c
+++ b/hw/display/milkymist-tmu2.c
@@ -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,
};
diff --git a/hw/display/milkymist-vgafb.c b/hw/display/milkymist-vgafb.c
index 177fdac7d..19ca25647 100644
--- a/hw/display/milkymist-vgafb.c
+++ b/hw/display/milkymist-vgafb.c
@@ -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,
};
diff --git a/hw/display/omap_lcd_template.h b/hw/display/omap_lcd_template.h
index 1025ff382..f0ce71fd6 100644
--- a/hw/display/omap_lcd_template.h
+++ b/hw/display/omap_lcd_template.h
@@ -27,7 +27,13 @@
* 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;
diff --git a/hw/display/omap_lcdc.c b/hw/display/omap_lcdc.c
index 07a5effe0..ce1058bf8 100644
--- a/hw/display/omap_lcdc.c
+++ b/hw/display/omap_lcdc.c
@@ -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;
diff --git a/hw/display/pl110.c b/hw/display/pl110.c
index c069c0b7f..d589959f1 100644
--- a/hw/display/pl110.c
+++ b/hw/display/pl110.c
@@ -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
diff --git a/hw/display/qxl.c b/hw/display/qxl.c
index 0e2682d28..919dc5cd3 100644
--- a/hw/display/qxl.c
+++ b/hw/display/qxl.c
@@ -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),
diff --git a/hw/display/qxl.h b/hw/display/qxl.h
index d2d49dd93..2ddf065e1 100644
--- a/hw/display/qxl.h
+++ b/hw/display/qxl.h
@@ -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 */
diff --git a/hw/display/ssd0323.c b/hw/display/ssd0323.c
index 6d1faf44a..14c1bf339 100644
--- a/hw/display/ssd0323.c
+++ b/hw/display/ssd0323.c
@@ -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;
}
diff --git a/hw/display/tc6393xb.c b/hw/display/tc6393xb.c
index 92f7120ac..da3ceceb0 100644
--- a/hw/display/tc6393xb.c
+++ b/hw/display/tc6393xb.c
@@ -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
index 332ababd8..000000000
--- a/hw/display/trace-events
+++ /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"
diff --git a/hw/display/vga.c b/hw/display/vga.c
index 2a88b3c1b..9ebc54f22 100644
--- a/hw/display/vga.c
+++ b/hw/display/vga.c
@@ -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)
diff --git a/hw/display/vga.h b/hw/display/vga.h
index 16886f5ee..d917046da 100644
--- a/hw/display/vga.h
+++ b/hw/display/vga.h
@@ -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. */
@@ -156,4 +156,4 @@
/* VGA graphics controller bit masks */
#define VGA_GR06_GRAPHICS_MODE 0x01
-#endif /* LINUX_VIDEO_VGA_H */
+#endif /* __linux_video_vga_h__ */
diff --git a/hw/display/vga_int.h b/hw/display/vga_int.h
index dd6c958da..3ce5544ef 100644
--- a/hw/display/vga_int.h
+++ b/hw/display/vga_int.h
@@ -21,11 +21,10 @@
* 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
diff --git a/hw/display/virtio-gpu-3d.c b/hw/display/virtio-gpu-3d.c
index 758d33a09..fa192946a 100644
--- a/hw/display/virtio-gpu-3d.c
+++ b/hw/display/virtio-gpu-3d.c
@@ -17,11 +17,10 @@
#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);
}
}
diff --git a/hw/display/virtio-gpu-pci.c b/hw/display/virtio-gpu-pci.c
index 34a724c75..a71b230d3 100644
--- a/hw/display/virtio-gpu-pci.c
+++ b/hw/display/virtio-gpu-pci.c
@@ -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++) {
diff --git a/hw/display/virtio-gpu.c b/hw/display/virtio-gpu.c
index 7fe6ed8bf..c181fb364 100644
--- a/hw/display/virtio-gpu.c
+++ b/hw/display/virtio-gpu.c
@@ -19,17 +19,12 @@
#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 = {
diff --git a/hw/display/virtio-vga.c b/hw/display/virtio-vga.c
index 5b510a17f..e58b165ae 100644
--- a/hw/display/virtio-vga.c
+++ b/hw/display/virtio-vga.c
@@ -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;
diff --git a/hw/display/xenfb.c b/hw/display/xenfb.c
index 46b7d5ede..9866dfda5 100644
--- a/hw/display/xenfb.c
+++ b/hw/display/xenfb.c
@@ -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
index f43eb0930..000000000
--- a/hw/display/xlnx_dp.c
+++ /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)
diff --git a/hw/dma/Makefile.objs b/hw/dma/Makefile.objs
index 087c8e685..a1abbcf74 100644
--- a/hw/dma/Makefile.objs
+++ b/hw/dma/Makefile.objs
@@ -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
diff --git a/hw/dma/bcm2835_dma.c b/hw/dma/bcm2835_dma.c
index 5d144a263..542117599 100644
--- a/hw/dma/bcm2835_dma.c
+++ b/hw/dma/bcm2835_dma.c
@@ -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)
diff --git a/hw/dma/pl080.c b/hw/dma/pl080.c
index 3bed5c339..9318108b8 100644
--- a/hw/dma/pl080.c
+++ b/hw/dma/pl080.c
@@ -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
diff --git a/hw/dma/pl330.c b/hw/dma/pl330.c
index c0bd9fec3..ea89ecb00 100644
--- a/hw/dma/pl330.c
+++ b/hw/dma/pl330.c
@@ -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
diff --git a/hw/dma/pxa2xx_dma.c b/hw/dma/pxa2xx_dma.c
index 634a4328f..2306abc35 100644
--- a/hw/dma/pxa2xx_dma.c
+++ b/hw/dma/pxa2xx_dma.c
@@ -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,
};
diff --git a/hw/dma/rc4030.c b/hw/dma/rc4030.c
index 2f2576faf..a06c2359a 100644
--- a/hw/dma/rc4030.c
+++ b/hw/dma/rc4030.c
@@ -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
index 22878dfdb..000000000
--- a/hw/dma/trace-events
+++ /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
index 3b1052343..000000000
--- a/hw/dma/xlnx-zynq-devcfg.c
+++ /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
index 8ceb21ddb..000000000
--- a/hw/dma/xlnx_dpdma.c
+++ /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)
diff --git a/hw/gpio/gpio_key.c b/hw/gpio/gpio_key.c
index b34aa49df..ef287727b 100644
--- a/hw/gpio/gpio_key.c
+++ b/hw/gpio/gpio_key.c
@@ -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)
diff --git a/hw/gpio/imx_gpio.c b/hw/gpio/imx_gpio.c
index f3574aa8f..ed7e247f5 100644
--- a/hw/gpio/imx_gpio.c
+++ b/hw/gpio/imx_gpio.c
@@ -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
diff --git a/hw/gpio/omap_gpio.c b/hw/gpio/omap_gpio.c
index dabef4a11..9b1b004fc 100644
--- a/hw/gpio/omap_gpio.c
+++ b/hw/gpio/omap_gpio.c
@@ -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" */
diff --git a/hw/gpio/pl061.c b/hw/gpio/pl061.c
index 4ae2aa156..29dc7fc38 100644
--- a/hw/gpio/pl061.c
+++ b/hw/gpio/pl061.c
@@ -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;
}
diff --git a/hw/gpio/zaurus.c b/hw/gpio/zaurus.c
index 15865e108..555da281c 100644
--- a/hw/gpio/zaurus.c
+++ b/hw/gpio/zaurus.c
@@ -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,
};
diff --git a/hw/i2c/Makefile.objs b/hw/i2c/Makefile.objs
index a081b8ef2..aeb8f38d7 100644
--- a/hw/i2c/Makefile.objs
+++ b/hw/i2c/Makefile.objs
@@ -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
index ce5b1f0fa..000000000
--- a/hw/i2c/aspeed_i2c.c
+++ /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;
-}
diff --git a/hw/i2c/bitbang_i2c.c b/hw/i2c/bitbang_i2c.c
index d3a29891f..6ed206020 100644
--- a/hw/i2c/bitbang_i2c.c
+++ b/hw/i2c/bitbang_i2c.c
@@ -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,
};
diff --git a/hw/i2c/core.c b/hw/i2c/core.c
index 4afbe0bde..ba22104af 100644
--- a/hw/i2c/core.c
+++ b/hw/i2c/core.c
@@ -10,21 +10,12 @@
#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;
}
diff --git a/hw/i2c/exynos4210_i2c.c b/hw/i2c/exynos4210_i2c.c
index c96fa7d7b..8c2a2c163 100644
--- a/hw/i2c/exynos4210_i2c.c
+++ b/hw/i2c/exynos4210_i2c.c
@@ -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
index 122721293..000000000
--- a/hw/i2c/i2c-ddc.c
+++ /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);
diff --git a/hw/i2c/imx_i2c.c b/hw/i2c/imx_i2c.c
index 37e5a62ce..e19d4fa74 100644
--- a/hw/i2c/imx_i2c.c
+++ b/hw/i2c/imx_i2c.c
@@ -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
diff --git a/hw/i2c/omap_i2c.c b/hw/i2c/omap_i2c.c
index f7c92ea00..67fbbff8e 100644
--- a/hw/i2c/omap_i2c.c
+++ b/hw/i2c/omap_i2c.c
@@ -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,
};
diff --git a/hw/i2c/smbus_ich9.c b/hw/i2c/smbus_ich9.c
index 48fab2262..498f03e83 100644
--- a/hw/i2c/smbus_ich9.c
+++ b/hw/i2c/smbus_ich9.c
@@ -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)
diff --git a/hw/i2c/versatile_i2c.c b/hw/i2c/versatile_i2c.c
index da9f298ee..fee3bc761 100644
--- a/hw/i2c/versatile_i2c.c
+++ b/hw/i2c/versatile_i2c.c
@@ -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)
diff --git a/hw/i386/Makefile.objs b/hw/i386/Makefile.objs
index 90e94ffef..b52d5b875 100644
--- a/hw/i386/Makefile.objs
+++ b/hw/i386/Makefile.objs
@@ -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
diff --git a/hw/i386/acpi-build.c b/hw/i386/acpi-build.c
index a26a4bb03..64770034f 100644
--- a/hw/i386/acpi-build.c
+++ b/hw/i386/acpi-build.c
@@ -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"
@@ -52,16 +51,13 @@
#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));
diff --git a/hw/i386/intel_iommu.c b/hw/i386/intel_iommu.c
index 28c31a2cd..347718f93 100644
--- a/hw/i386/intel_iommu.c
+++ b/hw/i386/intel_iommu.c
@@ -20,23 +20,16 @@
*/
#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,
};
diff --git a/hw/i386/intel_iommu_internal.h b/hw/i386/intel_iommu_internal.h
index 0829a5064..e5f514c6e 100644
--- a/hw/i386/intel_iommu_internal.h
+++ b/hw/i386/intel_iommu_internal.h
@@ -110,8 +110,6 @@
/* 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
@@ -174,19 +172,10 @@
#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 */
diff --git a/hw/i386/kvm/apic.c b/hw/i386/kvm/apic.c
index 2bd0de82b..3c7c8fa00 100644
--- a/hw/i386/kvm/apic.c
+++ b/hw/i386/kvm/apic.c
@@ -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;
diff --git a/hw/i386/kvm/clock.c b/hw/i386/kvm/clock.c
index 0f75dd385..a3b300cad 100644
--- a/hw/i386/kvm/clock.c
+++ b/hw/i386/kvm/clock.c
@@ -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"
diff --git a/hw/i386/kvm/i8254.c b/hw/i386/kvm/i8254.c
index 521a58498..a4462e5ca 100644
--- a/hw/i386/kvm/i8254.c
+++ b/hw/i386/kvm/i8254.c
@@ -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"
diff --git a/hw/i386/kvm/pci-assign.c b/hw/i386/kvm/pci-assign.c
index 8238fbc63..8abce52b7 100644
--- a/hw/i386/kvm/pci-assign.c
+++ b/hw/i386/kvm/pci-assign.c
@@ -20,10 +20,9 @@
* 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;
diff --git a/hw/i386/kvmvapic.c b/hw/i386/kvmvapic.c
index 3bf1ddd97..ff1e31a4d 100644
--- a/hw/i386/kvmvapic.c
+++ b/hw/i386/kvmvapic.c
@@ -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);
}
}
diff --git a/hw/i386/pc.c b/hw/i386/pc.c
index 022dd1b20..99437e0b7 100644
--- a/hw/i386/pc.c
+++ b/hw/i386/pc.c
@@ -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 },
{ }
},
};
diff --git a/hw/i386/pc_piix.c b/hw/i386/pc_piix.c
index a07dc816b..7f50116bc 100644
--- a/hw/i386/pc_piix.c
+++ b/hw/i386/pc_piix.c
@@ -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",\
diff --git a/hw/i386/pc_q35.c b/hw/i386/pc_q35.c
index c0b996192..04aae8958 100644
--- a/hw/i386/pc_q35.c
+++ b/hw/i386/pc_q35.c
@@ -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
index 7735e46ea..000000000
--- a/hw/i386/trace-events
+++ /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
index ce26b2a71..000000000
--- a/hw/i386/x86-iommu.c
+++ /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)
diff --git a/hw/ide/ahci.c b/hw/ide/ahci.c
index f3438ad78..a1e651635 100644
--- a/hw/ide/ahci.c
+++ b/hw/ide/ahci.c
@@ -22,17 +22,17 @@
*/
#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",
diff --git a/include/hw/ide/ahci.h b/hw/ide/ahci.h
index 0ca7c6582..bc777ed5c 100644
--- a/include/hw/ide/ahci.h
+++ b/hw/ide/ahci.h
@@ -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
diff --git a/hw/ide/atapi.c b/hw/ide/atapi.c
index 618967503..8592a4ae1 100644
--- a/hw/ide/atapi.c
+++ b/hw/ide/atapi.c
@@ -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,
diff --git a/hw/ide/cmd646.c b/hw/ide/cmd646.c
index 9ebb8d4fb..49294a531 100644
--- a/hw/ide/cmd646.c
+++ b/hw/ide/cmd646.c
@@ -23,15 +23,15 @@
* 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
diff --git a/hw/ide/core.c b/hw/ide/core.c
index 45b6df132..aa11f134d 100644
--- a/hw/ide/core.c
+++ b/hw/ide/core.c
@@ -23,10 +23,10 @@
* 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);
}
diff --git a/hw/ide/ich.c b/hw/ide/ich.c
index 459916977..0a13334ba 100644
--- a/hw/ide/ich.c
+++ b/hw/ide/ich.c
@@ -61,15 +61,16 @@
*/
#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)
diff --git a/include/hw/ide/internal.h b/hw/ide/internal.h
index 7824bc34c..d2c458f57 100644
--- a/include/hw/ide/internal.h
+++ b/hw/ide/internal.h
@@ -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);
diff --git a/hw/ide/isa.c b/hw/ide/isa.c
index 40213d662..eba567c87 100644
--- a/hw/ide/isa.c
+++ b/hw/ide/isa.c
@@ -23,13 +23,13 @@
* 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 */
diff --git a/hw/ide/macio.c b/hw/ide/macio.c
index 76f97c253..664328d17 100644
--- a/hw/ide/macio.c
+++ b/hw/ide/macio.c
@@ -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();
}
}
diff --git a/hw/ide/microdrive.c b/hw/ide/microdrive.c
index e3fd30e45..5c9db8047 100644
--- a/hw/ide/microdrive.c
+++ b/hw/ide/microdrive.c
@@ -23,13 +23,13 @@
* 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)
diff --git a/hw/ide/mmio.c b/hw/ide/mmio.c
index 6f12f456e..493f65a1d 100644
--- a/hw/ide/mmio.c
+++ b/hw/ide/mmio.c
@@ -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
diff --git a/hw/ide/pci.c b/hw/ide/pci.c
index 3cfb510af..8d56a00b1 100644
--- a/hw/ide/pci.c
+++ b/hw/ide/pci.c
@@ -23,14 +23,14 @@
* 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
diff --git a/include/hw/ide/pci.h b/hw/ide/pci.h
index dbc6a0383..0f2d4b91a 100644
--- a/include/hw/ide/pci.h
+++ b/hw/ide/pci.h
@@ -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
diff --git a/hw/ide/piix.c b/hw/ide/piix.c
index c190fcaa3..6d76ce980 100644
--- a/hw/ide/piix.c
+++ b/hw/ide/piix.c
@@ -24,15 +24,15 @@
*/
#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)
{
diff --git a/hw/ide/qdev.c b/hw/ide/qdev.c
index 67c76bfcd..4bc74a32d 100644
--- a/hw/ide/qdev.c
+++ b/hw/ide/qdev.c
@@ -17,11 +17,11 @@
* 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),\
diff --git a/hw/ide/via.c b/hw/ide/via.c
index 5b32ecb38..d3f72267a 100644
--- a/hw/ide/via.c
+++ b/hw/ide/via.c
@@ -24,15 +24,15 @@
* 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)
diff --git a/hw/input/hid.c b/hw/input/hid.c
index 5e2850e65..d92c7463b 100644
--- a/hw/input/hid.c
+++ b/hw/input/hid.c
@@ -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++) {
diff --git a/hw/input/pckbd.c b/hw/input/pckbd.c
index dc57e2c76..1d932ec19 100644
--- a/hw/input/pckbd.c
+++ b/hw/input/pckbd.c
@@ -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)
diff --git a/hw/input/pl050.c b/hw/input/pl050.c
index be9cd57b1..3092b0fe3 100644
--- a/hw/input/pl050.c
+++ b/hw/input/pl050.c
@@ -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
index 8c4003f36..000000000
--- a/hw/input/trace-events
+++ /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"
diff --git a/hw/input/virtio-input.c b/hw/input/virtio-input.c
index ccdf7308a..f59749a94 100644
--- a/hw/input/virtio-input.c
+++ b/hw/input/virtio-input.c
@@ -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,
};
/* ----------------------------------------------------------------- */
diff --git a/hw/intc/Makefile.objs b/hw/intc/Makefile.objs
index 05ec21b21..0e47f0f9e 100644
--- a/hw/intc/Makefile.objs
+++ b/hw/intc/Makefile.objs
@@ -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
diff --git a/hw/intc/allwinner-a10-pic.c b/hw/intc/allwinner-a10-pic.c
index 11f13663c..dc971a160 100644
--- a/hw/intc/allwinner-a10-pic.c
+++ b/hw/intc/allwinner-a10-pic.c
@@ -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)
{
diff --git a/hw/intc/apic.c b/hw/intc/apic.c
index 45887d99c..28c2ea540 100644
--- a/hw/intc/apic.c
+++ b/hw/intc/apic.c
@@ -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;
diff --git a/hw/intc/apic_common.c b/hw/intc/apic_common.c
index 14ac43c18..4abe145c6 100644
--- a/hw/intc/apic_common.c
+++ b/hw/intc/apic_common.c
@@ -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()
diff --git a/hw/intc/arm_gic.c b/hw/intc/arm_gic.c
index b30cc9174..f55124174 100644
--- a/hw/intc/arm_gic.c
+++ b/hw/intc/arm_gic.c
@@ -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;
}
diff --git a/hw/intc/arm_gic_kvm.c b/hw/intc/arm_gic_kvm.c
index 5593cdb3e..bc85ab769 100644
--- a/hw/intc/arm_gic_kvm.c
+++ b/hw/intc/arm_gic_kvm.c
@@ -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"
diff --git a/hw/intc/arm_gicv2m.c b/hw/intc/arm_gicv2m.c
index 3922fbc1c..e8b5177dc 100644
--- a/hw/intc/arm_gicv2m.c
+++ b/hw/intc/arm_gicv2m.c
@@ -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
index 8a6c64721..000000000
--- a/hw/intc/arm_gicv3.c
+++ /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)
diff --git a/hw/intc/arm_gicv3_common.c b/hw/intc/arm_gicv3_common.c
index 0f8c4b86e..b9d3824f2 100644
--- a/hw/intc/arm_gicv3_common.c
+++ b/hw/intc/arm_gicv3_common.c
@@ -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
@@ -23,10 +22,7 @@
#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
index 4633172be..000000000
--- a/hw/intc/arm_gicv3_cpuif.c
+++ /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
index 3ea3dd0d4..000000000
--- a/hw/intc/arm_gicv3_dist.c
+++ /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);
-}
diff --git a/hw/intc/arm_gicv3_kvm.c b/hw/intc/arm_gicv3_kvm.c
index 711fde38f..acc173004 100644
--- a/hw/intc/arm_gicv3_kvm.c
+++ b/hw/intc/arm_gicv3_kvm.c
@@ -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
index 77e5cfa32..000000000
--- a/hw/intc/arm_gicv3_redist.c
+++ /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);
-}
diff --git a/hw/intc/armv7m_nvic.c b/hw/intc/armv7m_nvic.c
index 06d8db6bd..669e82adf 100644
--- a/hw/intc/armv7m_nvic.c
+++ b/hw/intc/armv7m_nvic.c
@@ -13,13 +13,11 @@
#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. */
diff --git a/hw/intc/aspeed_vic.c b/hw/intc/aspeed_vic.c
index 2370e7485..19a0ff748 100644
--- a/hw/intc/aspeed_vic.c
+++ b/hw/intc/aspeed_vic.c
@@ -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
diff --git a/hw/intc/bcm2835_ic.c b/hw/intc/bcm2835_ic.c
index 00d25306f..80513b28f 100644
--- a/hw/intc/bcm2835_ic.c
+++ b/hw/intc/bcm2835_ic.c
@@ -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
diff --git a/hw/intc/bcm2836_control.c b/hw/intc/bcm2836_control.c
index cfa5bc736..d0271810c 100644
--- a/hw/intc/bcm2836_control.c
+++ b/hw/intc/bcm2836_control.c
@@ -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
diff --git a/hw/intc/etraxfs_pic.c b/hw/intc/etraxfs_pic.c
index 64a6f4b4b..48f947706 100644
--- a/hw/intc/etraxfs_pic.c
+++ b/hw/intc/etraxfs_pic.c
@@ -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,
};
diff --git a/hw/intc/exynos4210_combiner.c b/hw/intc/exynos4210_combiner.c
index f19a7062b..dc0c90326 100644
--- a/hw/intc/exynos4210_combiner.c
+++ b/hw/intc/exynos4210_combiner.c
@@ -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,
};
diff --git a/hw/intc/exynos4210_gic.c b/hw/intc/exynos4210_gic.c
index fd7a8f305..4f7e89f7b 100644
--- a/hw/intc/exynos4210_gic.c
+++ b/hw/intc/exynos4210_gic.c
@@ -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,
};
diff --git a/hw/intc/gic_internal.h b/hw/intc/gic_internal.h
index 3f311740d..20c1e8a24 100644
--- a/hw/intc/gic_internal.h
+++ b/hw/intc/gic_internal.h
@@ -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
index 8f3567eda..000000000
--- a/hw/intc/gicv3_internal.h
+++ /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 */
diff --git a/hw/intc/grlib_irqmp.c b/hw/intc/grlib_irqmp.c
index ac7e63f38..f5ca8f752 100644
--- a/hw/intc/grlib_irqmp.c
+++ b/hw/intc/grlib_irqmp.c
@@ -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,
};
diff --git a/hw/intc/i8259.c b/hw/intc/i8259.c
index c2607a586..bb43669b9 100644
--- a/hw/intc/i8259.c
+++ b/hw/intc/i8259.c
@@ -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 */
diff --git a/hw/intc/imx_avic.c b/hw/intc/imx_avic.c
index 813e587a6..702765577 100644
--- a/hw/intc/imx_avic.c
+++ b/hw/intc/imx_avic.c
@@ -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,
};
diff --git a/hw/intc/ioapic.c b/hw/intc/ioapic.c
index 31791b098..378e663f6 100644
--- a/hw/intc/ioapic.c
+++ b/hw/intc/ioapic.c
@@ -21,18 +21,13 @@
*/
#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 = {
diff --git a/hw/intc/lm32_pic.c b/hw/intc/lm32_pic.c
index 3dad01c5b..edc08f184 100644
--- a/hw/intc/lm32_pic.c
+++ b/hw/intc/lm32_pic.c
@@ -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
index 6e257730f..000000000
--- a/hw/intc/mips_gic.c
+++ /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)
diff --git a/hw/intc/omap_intc.c b/hw/intc/omap_intc.c
index 877be6797..336882510 100644
--- a/hw/intc/omap_intc.c
+++ b/hw/intc/omap_intc.c
@@ -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,
};
diff --git a/hw/intc/openpic.c b/hw/intc/openpic.c
index 4349e45e0..2d3769310 100644
--- a/hw/intc/openpic.c
+++ b/hw/intc/openpic.c
@@ -44,7 +44,6 @@
#include "qapi/error.h"
#include "qemu/bitops.h"
#include "qapi/qmp/qerror.h"
-#include "qemu/log.h"
//#define DEBUG_OPENPIC
diff --git a/hw/intc/openpic_kvm.c b/hw/intc/openpic_kvm.c
index 0518e017c..e47e94f2c 100644
--- a/hw/intc/openpic_kvm.c
+++ b/hw/intc/openpic_kvm.c
@@ -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"
diff --git a/hw/intc/pl190.c b/hw/intc/pl190.c
index 55ea15de7..5ecbc4a48 100644
--- a/hw/intc/pl190.c
+++ b/hw/intc/pl190.c
@@ -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,
};
diff --git a/hw/intc/s390_flic.c b/hw/intc/s390_flic.c
index 6ab29efc6..bc75fa7d9 100644
--- a/hw/intc/s390_flic.c
+++ b/hw/intc/s390_flic.c
@@ -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 = {
diff --git a/hw/intc/s390_flic_kvm.c b/hw/intc/s390_flic_kvm.c
index fef808011..02449b390 100644
--- a/hw/intc/s390_flic_kvm.c
+++ b/hw/intc/s390_flic_kvm.c
@@ -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 = {
diff --git a/hw/intc/slavio_intctl.c b/hw/intc/slavio_intctl.c
index e82e89362..c9486ed99 100644
--- a/hw/intc/slavio_intctl.c
+++ b/hw/intc/slavio_intctl.c
@@ -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
index f12192c08..000000000
--- a/hw/intc/trace-events
+++ /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"
diff --git a/hw/intc/xics.c b/hw/intc/xics.c
index cd48f4204..8659be017 100644
--- a/hw/intc/xics.c
+++ b/hw/intc/xics.c
@@ -32,11 +32,12 @@
#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);
}
diff --git a/hw/intc/xics_kvm.c b/hw/intc/xics_kvm.c
index edbd62fd1..9029d9ee0 100644
--- a/hw/intc/xics_kvm.c
+++ b/hw/intc/xics_kvm.c
@@ -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
index 618826dac..000000000
--- a/hw/intc/xics_spapr.c
+++ /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)
diff --git a/hw/ipack/ipack.c b/hw/ipack/ipack.c
index 6021e6d13..5f99ed9a7 100644
--- a/hw/ipack/ipack.c
+++ b/hw/ipack/ipack.c
@@ -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.
diff --git a/hw/ipack/tpci200.c b/hw/ipack/tpci200.c
index 4dfa6b33f..fdda6f414 100644
--- a/hw/ipack/tpci200.c
+++ b/hw/ipack/tpci200.c
@@ -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.
diff --git a/hw/ipmi/ipmi.c b/hw/ipmi/ipmi.c
index f09f217e7..6adec1e99 100644
--- a/hw/ipmi/ipmi.c
+++ b/hw/ipmi/ipmi.c
@@ -30,13 +30,6 @@
#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;
+}
diff --git a/hw/ipmi/ipmi_bmc_extern.c b/hw/ipmi/ipmi_bmc_extern.c
index 157879e17..fe12112a2 100644
--- a/hw/ipmi/ipmi_bmc_extern.c
+++ b/hw/ipmi/ipmi_bmc_extern.c
@@ -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();
}
diff --git a/hw/ipmi/isa_ipmi_bt.c b/hw/ipmi/isa_ipmi_bt.c
index f03661715..aaea12ecd 100644
--- a/hw/ipmi/isa_ipmi_bt.c
+++ b/hw/ipmi/isa_ipmi_bt.c
@@ -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 = {
diff --git a/hw/ipmi/isa_ipmi_kcs.c b/hw/ipmi/isa_ipmi_kcs.c
index 9a38f8a28..2742ce06c 100644
--- a/hw/ipmi/isa_ipmi_kcs.c
+++ b/hw/ipmi/isa_ipmi_kcs.c
@@ -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 = {
diff --git a/hw/isa/isa-bus.c b/hw/isa/isa-bus.c
index ce74db232..7aa115caf 100644
--- a/hw/isa/isa-bus.c
+++ b/hw/isa/isa-bus.c
@@ -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);
diff --git a/hw/isa/lpc_ich9.c b/hw/isa/lpc_ich9.c
index 10d1ee8b9..99cd3ba9e 100644
--- a/hw/isa/lpc_ich9.c
+++ b/hw/isa/lpc_ich9.c
@@ -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
index 9faca41a9..000000000
--- a/hw/isa/trace-events
+++ /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"
diff --git a/hw/lm32/lm32.h b/hw/lm32/lm32.h
index db9eb29ea..18aa6fdc1 100644
--- a/hw/lm32/lm32.h
+++ b/hw/lm32/lm32.h
@@ -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
diff --git a/hw/lm32/lm32_boards.c b/hw/lm32/lm32_boards.c
index 8f0c3079d..c0290560f 100644
--- a/hw/lm32/lm32_boards.c
+++ b/hw/lm32/lm32_boards.c
@@ -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;
diff --git a/hw/lm32/milkymist-hw.h b/hw/lm32/milkymist-hw.h
index 4418b44ca..c8dfb4d2d 100644
--- a/hw/lm32/milkymist-hw.h
+++ b/hw/lm32/milkymist-hw.h
@@ -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 */
diff --git a/hw/lm32/milkymist.c b/hw/lm32/milkymist.c
index 5cae0f19d..96e6f4dc2 100644
--- a/hw/lm32/milkymist.c
+++ b/hw/lm32/milkymist.c
@@ -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;
diff --git a/hw/mem/nvdimm.c b/hw/mem/nvdimm.c
index 7895805a2..0a602f28b 100644
--- a/hw/mem/nvdimm.c
+++ b/hw/mem/nvdimm.c
@@ -23,153 +23,20 @@
*/
#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)
diff --git a/hw/mem/pc-dimm.c b/hw/mem/pc-dimm.c
index 9e8dab0e8..9e7de5682 100644
--- a/hw/mem/pc-dimm.c
+++ b/hw/mem/pc-dimm.c
@@ -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 = {
diff --git a/hw/microblaze/boot.h b/hw/microblaze/boot.h
index dd1090d8b..0eb7f8e4f 100644
--- a/hw/microblaze/boot.h
+++ b/hw/microblaze/boot.h
@@ -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 __ */
diff --git a/hw/microblaze/petalogix_ml605_mmu.c b/hw/microblaze/petalogix_ml605_mmu.c
index 4968bdbb2..07527b677 100644
--- a/hw/microblaze/petalogix_ml605_mmu.c
+++ b/hw/microblaze/petalogix_ml605_mmu.c
@@ -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);
}
diff --git a/hw/microblaze/petalogix_s3adsp1800_mmu.c b/hw/microblaze/petalogix_s3adsp1800_mmu.c
index 423bcd7f6..f821e1cfe 100644
--- a/hw/microblaze/petalogix_s3adsp1800_mmu.c
+++ b/hw/microblaze/petalogix_s3adsp1800_mmu.c
@@ -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");
diff --git a/hw/mips/cps.c b/hw/mips/cps.c
index 4ef337d5c..1bafbbb27 100644
--- a/hw/mips/cps.c
+++ b/hw/mips/cps.c
@@ -26,8 +26,13 @@
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()
};
diff --git a/hw/mips/cputimer.c b/hw/mips/cputimer.c
index 8a166b3ea..efb227d06 100644
--- a/hw/mips/cputimer.c
+++ b/hw/mips/cputimer.c
@@ -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.
diff --git a/hw/mips/gt64xxx_pci.c b/hw/mips/gt64xxx_pci.c
index 4811843ab..3f4523df2 100644
--- a/hw/mips/gt64xxx_pci.c
+++ b/hw/mips/gt64xxx_pci.c
@@ -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");
diff --git a/hw/mips/mips_fulong2e.c b/hw/mips/mips_fulong2e.c
index 889cdc7ca..bdb716e72 100644
--- a/hw/mips/mips_fulong2e.c
+++ b/hw/mips/mips_fulong2e.c
@@ -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]));
diff --git a/hw/mips/mips_int.c b/hw/mips/mips_int.c
index 48192d22f..59081f9d1 100644
--- a/hw/mips/mips_int.c
+++ b/hw/mips/mips_int.c
@@ -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;
diff --git a/hw/mips/mips_jazz.c b/hw/mips/mips_jazz.c
index 73f6c9fac..ac7c64125 100644
--- a/hw/mips/mips_jazz.c
+++ b/hw/mips/mips_jazz.c
@@ -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);
diff --git a/hw/mips/mips_malta.c b/hw/mips/mips_malta.c
index e90857ee0..fa769e5c0 100644
--- a/hw/mips/mips_malta.c
+++ b/hw/mips/mips_malta.c
@@ -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;
}
diff --git a/hw/mips/mips_mipssim.c b/hw/mips/mips_mipssim.c
index 1b9119500..a2c2a1646 100644
--- a/hw/mips/mips_mipssim.c
+++ b/hw/mips/mips_mipssim.c
@@ -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",
diff --git a/hw/mips/mips_r4k.c b/hw/mips/mips_r4k.c
index 16a59c779..21aca981c 100644
--- a/hw/mips/mips_r4k.c
+++ b/hw/mips/mips_r4k.c
@@ -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",
diff --git a/hw/misc/Makefile.objs b/hw/misc/Makefile.objs
index 4cfbd1024..93f952880 100644
--- a/hw/misc/Makefile.objs
+++ b/hw/misc/Makefile.objs
@@ -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
diff --git a/hw/misc/arm11scu.c b/hw/misc/arm11scu.c
index 7042ce11e..5e54b494b 100644
--- a/hw/misc/arm11scu.c
+++ b/hw/misc/arm11scu.c
@@ -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)
diff --git a/hw/misc/arm_integrator_debug.c b/hw/misc/arm_integrator_debug.c
index 8a5f29559..902605fef 100644
--- a/hw/misc/arm_integrator_debug.c
+++ b/hw/misc/arm_integrator_debug.c
@@ -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)
diff --git a/hw/misc/arm_l2x0.c b/hw/misc/arm_l2x0.c
index 66a0787c4..7e179f1a4 100644
--- a/hw/misc/arm_l2x0.c
+++ b/hw/misc/arm_l2x0.c
@@ -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,
};
diff --git a/hw/misc/arm_sysctl.c b/hw/misc/arm_sysctl.c
index 852400870..34d90d523 100644
--- a/hw/misc/arm_sysctl.c
+++ b/hw/misc/arm_sysctl.c
@@ -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
index c7e2c8263..000000000
--- a/hw/misc/aspeed_scu.c
+++ /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
index e4a7ba41d..000000000
--- a/hw/misc/auxbus.c
+++ /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)
diff --git a/hw/misc/bcm2835_mbox.c b/hw/misc/bcm2835_mbox.c
index e97cc814a..263280fd4 100644
--- a/hw/misc/bcm2835_mbox.c
+++ b/hw/misc/bcm2835_mbox.c
@@ -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
diff --git a/hw/misc/bcm2835_property.c b/hw/misc/bcm2835_property.c
index 70eaafd32..530411f84 100644
--- a/hw/misc/bcm2835_property.c
+++ b/hw/misc/bcm2835_property.c
@@ -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 */
diff --git a/hw/misc/exynos4210_pmu.c b/hw/misc/exynos4210_pmu.c
index e30dbc7d3..889abadfe 100644
--- a/hw/misc/exynos4210_pmu.c
+++ b/hw/misc/exynos4210_pmu.c
@@ -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,
};
diff --git a/hw/misc/hyperv_testdev.c b/hw/misc/hyperv_testdev.c
index 6cae9e901..1883fd7f2 100644
--- a/hw/misc/hyperv_testdev.c
+++ b/hw/misc/hyperv_testdev.c
@@ -12,11 +12,11 @@
*/
#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"
diff --git a/hw/misc/imx25_ccm.c b/hw/misc/imx25_ccm.c
index 5cd8c0a9a..225604d82 100644
--- a/hw/misc/imx25_ccm.c
+++ b/hw/misc/imx25_ccm.c
@@ -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
diff --git a/hw/misc/imx31_ccm.c b/hw/misc/imx31_ccm.c
index 1c03e52c4..80c164716 100644
--- a/hw/misc/imx31_ccm.c
+++ b/hw/misc/imx31_ccm.c
@@ -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 */
diff --git a/hw/misc/imx6_ccm.c b/hw/misc/imx6_ccm.c
index 17e15d4c9..4e1d49da6 100644
--- a/hw/misc/imx6_ccm.c
+++ b/hw/misc/imx6_ccm.c
@@ -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
index 8bb682957..000000000
--- a/hw/misc/imx6_src.c
+++ /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)
diff --git a/hw/misc/imx_ccm.c b/hw/misc/imx_ccm.c
index 7f239a41d..986d890ca 100644
--- a/hw/misc/imx_ccm.c
+++ b/hw/misc/imx_ccm.c
@@ -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
diff --git a/hw/misc/ivshmem.c b/hw/misc/ivshmem.c
index 40a2ebca2..e40f23bfc 100644
--- a/hw/misc/ivshmem.c
+++ b/hw/misc/ivshmem.c
@@ -33,9 +33,12 @@
#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;
}
diff --git a/hw/misc/macio/cuda.c b/hw/misc/macio/cuda.c
index 05c02fb3a..f15f30110 100644
--- a/hw/misc/macio/cuda.c
+++ b/hw/misc/macio/cuda.c
@@ -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 */
diff --git a/hw/misc/macio/mac_dbdma.c b/hw/misc/macio/mac_dbdma.c
index 15452b9a2..6051f17db 100644
--- a/hw/misc/macio/mac_dbdma.c
+++ b/hw/misc/macio/mac_dbdma.c
@@ -41,26 +41,16 @@
#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)
diff --git a/hw/misc/max111x.c b/hw/misc/max111x.c
index 2a277bdb8..9014f0f70 100644
--- a/hw/misc/max111x.c
+++ b/hw/misc/max111x.c
@@ -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 = {
diff --git a/hw/misc/milkymist-hpdmc.c b/hw/misc/milkymist-hpdmc.c
index e6140eec6..b97000fc4 100644
--- a/hw/misc/milkymist-hpdmc.c
+++ b/hw/misc/milkymist-hpdmc.c
@@ -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"
diff --git a/hw/misc/milkymist-pfpu.c b/hw/misc/milkymist-pfpu.c
index 1da21a643..57acd7b36 100644
--- a/hw/misc/milkymist-pfpu.c
+++ b/hw/misc/milkymist-pfpu.c
@@ -18,7 +18,7 @@
*
*
* Specification available at:
- * http://milkymist.walle.cc/socdoc/pfpu.pdf
+ * http://www.milkymist.org/socdoc/pfpu.pdf
*
*/
diff --git a/hw/misc/mips_cmgcr.c b/hw/misc/mips_cmgcr.c
index b3ba16694..37be23995 100644
--- a/hw/misc/mips_cmgcr.c
+++ b/hw/misc/mips_cmgcr.c
@@ -11,24 +11,17 @@
#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 = {
diff --git a/hw/misc/mips_cpc.c b/hw/misc/mips_cpc.c
index 6d345745f..d2b8e42da 100644
--- a/hw/misc/mips_cpc.c
+++ b/hw/misc/mips_cpc.c
@@ -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;
}
}
diff --git a/hw/misc/mips_itu.c b/hw/misc/mips_itu.c
index ef935b51a..da5455062 100644
--- a/hw/misc/mips_itu.c
+++ b/hw/misc/mips_itu.c
@@ -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"
diff --git a/hw/misc/mst_fpga.c b/hw/misc/mst_fpga.c
index a10f0496f..48d7dfb2d 100644
--- a/hw/misc/mst_fpga.c
+++ b/hw/misc/mst_fpga.c
@@ -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,
};
diff --git a/hw/misc/pc-testdev.c b/hw/misc/pc-testdev.c
index b81d82008..086893dcc 100644
--- a/hw/misc/pc-testdev.c
+++ b/hw/misc/pc-testdev.c
@@ -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"
diff --git a/hw/misc/pci-testdev.c b/hw/misc/pci-testdev.c
index 7d5990213..2f2e98977 100644
--- a/hw/misc/pci-testdev.c
+++ b/hw/misc/pci-testdev.c
@@ -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;
diff --git a/hw/misc/stm32f2xx_syscfg.c b/hw/misc/stm32f2xx_syscfg.c
index 7c45833d0..d0d7076ef 100644
--- a/hw/misc/stm32f2xx_syscfg.c
+++ b/hw/misc/stm32f2xx_syscfg.c
@@ -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
index 0cc556ca9..000000000
--- a/hw/misc/trace-events
+++ /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
diff --git a/hw/misc/vmport.c b/hw/misc/vmport.c
index c763811a9..689678980 100644
--- a/hw/misc/vmport.c
+++ b/hw/misc/vmport.c
@@ -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
diff --git a/hw/misc/zynq-xadc.c b/hw/misc/zynq-xadc.c
index 14906103c..71fbccd79 100644
--- a/hw/misc/zynq-xadc.c
+++ b/hw/misc/zynq-xadc.c
@@ -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,
diff --git a/hw/misc/zynq_slcr.c b/hw/misc/zynq_slcr.c
index 789121900..b1b7591ef 100644
--- a/hw/misc/zynq_slcr.c
+++ b/hw/misc/zynq_slcr.c
@@ -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
diff --git a/hw/net/Makefile.objs b/hw/net/Makefile.objs
index 610ed3e7a..64d044923 100644
--- a/hw/net/Makefile.objs
+++ b/hw/net/Makefile.objs
@@ -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
diff --git a/hw/net/allwinner_emac.c b/hw/net/allwinner_emac.c
index 50e8361e5..16d4b63ba 100644
--- a/hw/net/allwinner_emac.c
+++ b/hw/net/allwinner_emac.c
@@ -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,
diff --git a/hw/net/cadence_gem.c b/hw/net/cadence_gem.c
index db1b301e7..0346f3e33 100644
--- a/hw/net/cadence_gem.c
+++ b/hw/net/cadence_gem.c
@@ -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,
diff --git a/hw/net/dp8393x.c b/hw/net/dp8393x.c
index 17f0338d1..0fa652c39 100644
--- a/hw/net/dp8393x.c
+++ b/hw/net/dp8393x.c
@@ -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,
diff --git a/hw/net/e1000.c b/hw/net/e1000.c
index 93249497f..8e79b550e 100644
--- a/hw/net/e1000.c
+++ b/hw/net/e1000.c
@@ -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);
diff --git a/hw/net/e1000_regs.h b/hw/net/e1000_regs.h
index 23eed50b9..1c40244ab 100644
--- a/hw/net/e1000_regs.h
+++ b/hw/net/e1000_regs.h
@@ -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
@@ -104,7 +104,6 @@
#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)
*
@@ -136,11 +135,8 @@
#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 */
@@ -149,7 +145,6 @@
#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 */
@@ -166,10 +161,6 @@
#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 */
@@ -178,12 +169,9 @@
#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 */
@@ -191,17 +179,11 @@
#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 */
@@ -210,33 +192,22 @@
#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 */
@@ -317,15 +288,9 @@
#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 */
@@ -335,57 +300,27 @@
#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 */
@@ -394,85 +329,6 @@
#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 */
@@ -488,40 +344,6 @@
#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 */
@@ -601,18 +423,6 @@
#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 */
@@ -661,11 +471,6 @@
#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 */
@@ -757,15 +562,6 @@
#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 */
@@ -788,17 +584,7 @@
#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 */
@@ -807,7 +593,6 @@
#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 */
@@ -832,13 +617,9 @@
#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 */
@@ -853,8 +634,6 @@
#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 */
@@ -885,8 +664,6 @@
#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
@@ -907,18 +684,6 @@
#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 */
@@ -946,21 +711,6 @@
#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
index bad43f474..000000000
--- a/hw/net/e1000e.c
+++ /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
index badb1feb7..000000000
--- a/hw/net/e1000e_core.c
+++ /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
index 5f413a9e0..000000000
--- a/hw/net/e1000e_core.h
+++ /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
index eb0e09713..000000000
--- a/hw/net/e1000x_common.c
+++ /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
index 21bf28e0c..000000000
--- a/hw/net/e1000x_common.h
+++ /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);
diff --git a/hw/net/eepro100.c b/hw/net/eepro100.c
index bab4dbfc9..9b4b9b59d 100644
--- a/hw/net/eepro100.c
+++ b/hw/net/eepro100.c
@@ -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,
};
diff --git a/hw/net/etraxfs_eth.c b/hw/net/etraxfs_eth.c
index efaa49faa..05495ec40 100644
--- a/hw/net/etraxfs_eth.c
+++ b/hw/net/etraxfs_eth.c
@@ -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,
diff --git a/hw/net/fsl_etsec/etsec.c b/hw/net/fsl_etsec/etsec.c
index b5c777fbf..1e35f7f8c 100644
--- a/hw/net/fsl_etsec/etsec.c
+++ b/hw/net/fsl_etsec/etsec.c
@@ -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,
diff --git a/hw/net/fsl_etsec/etsec.h b/hw/net/fsl_etsec/etsec.h
index 30c828e24..e7dc0a4b9 100644
--- a/hw/net/fsl_etsec/etsec.h
+++ b/hw/net/fsl_etsec/etsec.h
@@ -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_ */
diff --git a/hw/net/fsl_etsec/registers.h b/hw/net/fsl_etsec/registers.h
index c4ed2b9d6..6fb96842b 100644
--- a/hw/net/fsl_etsec/registers.h
+++ b/hw/net/fsl_etsec/registers.h
@@ -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_ */
diff --git a/hw/net/fsl_etsec/rings.c b/hw/net/fsl_etsec/rings.c
index 79d2f14dd..ed1de7da9 100644
--- a/hw/net/fsl_etsec/rings.c
+++ b/hw/net/fsl_etsec/rings.c
@@ -23,7 +23,7 @@
*/
#include "qemu/osdep.h"
#include "net/checksum.h"
-#include "qemu/log.h"
+
#include "etsec.h"
#include "registers.h"
diff --git a/hw/net/imx_fec.c b/hw/net/imx_fec.c
index 1c415ab3b..e60e3380e 100644
--- a/hw/net/imx_fec.c
+++ b/hw/net/imx_fec.c
@@ -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>
@@ -55,153 +52,30 @@
} \
} 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)
diff --git a/hw/net/lan9118.c b/hw/net/lan9118.c
index 4615d873b..08dc474d6 100644
--- a/hw/net/lan9118.c
+++ b/hw/net/lan9118.c
@@ -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,
diff --git a/hw/net/lance.c b/hw/net/lance.c
index 573d724bc..6253d2103 100644
--- a/hw/net/lance.c
+++ b/hw/net/lance.c
@@ -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,
diff --git a/hw/net/mcf_fec.c b/hw/net/mcf_fec.c
index 0ee8ad9d6..7c0398ed9 100644
--- a/hw/net/mcf_fec.c
+++ b/hw/net/mcf_fec.c
@@ -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,
};
diff --git a/hw/net/milkymist-minimac2.c b/hw/net/milkymist-minimac2.c
index c3a12e119..1e147c33c 100644
--- a/hw/net/milkymist-minimac2.c
+++ b/hw/net/milkymist-minimac2.c
@@ -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,
};
diff --git a/hw/net/mipsnet.c b/hw/net/mipsnet.c
index 5a63df7cc..cf8b8236d 100644
--- a/hw/net/mipsnet.c
+++ b/hw/net/mipsnet.c
@@ -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,
};
diff --git a/hw/net/ne2000-isa.c b/hw/net/ne2000-isa.c
index f3455339e..a7f5a9464 100644
--- a/hw/net/ne2000-isa.c
+++ b/hw/net/ne2000-isa.c
@@ -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)
diff --git a/hw/net/ne2000.c b/hw/net/ne2000.c
index 798d681e2..f0feaf96b 100644
--- a/hw/net/ne2000.c
+++ b/hw/net/ne2000.c
@@ -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,
};
diff --git a/hw/net/ne2000.h b/hw/net/ne2000.h
index d213dccae..d022b28fc 100644
--- a/hw/net/ne2000.h
+++ b/hw/net/ne2000.h
@@ -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
index 1019b50c1..000000000
--- a/hw/net/net_rx_pkt.c
+++ /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
index 7adf0fad5..000000000
--- a/hw/net/net_rx_pkt.h
+++ /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
index 212ecc62f..000000000
--- a/hw/net/net_tx_pkt.h
+++ /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
diff --git a/hw/net/opencores_eth.c b/hw/net/opencores_eth.c
index 268d6a789..c6094fbb5 100644
--- a/hw/net/opencores_eth.c
+++ b/hw/net/opencores_eth.c
@@ -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"
@@ -56,6 +55,12 @@
/* 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;
diff --git a/hw/net/pcnet-pci.c b/hw/net/pcnet-pci.c
index 0acf8a487..595439a65 100644
--- a/hw/net/pcnet-pci.c
+++ b/hw/net/pcnet-pci.c
@@ -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,
diff --git a/hw/net/pcnet.h b/hw/net/pcnet.h
index 40831a784..dec8de834 100644
--- a/hw/net/pcnet.h
+++ b/hw/net/pcnet.h
@@ -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
diff --git a/hw/net/rocker/rocker.h b/hw/net/rocker/rocker.h
index 7ae0495d9..f9c80f801 100644
--- a/hw/net/rocker/rocker.h
+++ b/hw/net/rocker/rocker.h
@@ -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_ */
diff --git a/hw/net/rocker/rocker_desc.h b/hw/net/rocker/rocker_desc.h
index 1dec33561..d4041f5c4 100644
--- a/hw/net/rocker/rocker_desc.h
+++ b/hw/net/rocker/rocker_desc.h
@@ -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"
diff --git a/hw/net/rocker/rocker_fp.c b/hw/net/rocker/rocker_fp.c
index 1305ac36c..0149899c6 100644
--- a/hw/net/rocker/rocker_fp.c
+++ b/hw/net/rocker/rocker_fp.c
@@ -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,
diff --git a/hw/net/rocker/rocker_fp.h b/hw/net/rocker/rocker_fp.h
index dbe1dd329..04592bbfd 100644
--- a/hw/net/rocker/rocker_fp.h
+++ b/hw/net/rocker/rocker_fp.h
@@ -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_ */
diff --git a/hw/net/rocker/rocker_hw.h b/hw/net/rocker/rocker_hw.h
index 1786323fa..8c5083032 100644
--- a/hw/net/rocker/rocker_hw.h
+++ b/hw/net/rocker/rocker_hw.h
@@ -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_ */
diff --git a/hw/net/rocker/rocker_of_dpa.c b/hw/net/rocker/rocker_of_dpa.c
index 9b1e0d244..0a134ebca 100644
--- a/hw/net/rocker/rocker_of_dpa.c
+++ b/hw/net/rocker/rocker_of_dpa.c
@@ -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;
diff --git a/hw/net/rocker/rocker_of_dpa.h b/hw/net/rocker/rocker_of_dpa.h
index 01c7a97d0..f3f6d7780 100644
--- a/hw/net/rocker/rocker_of_dpa.h
+++ b/hw/net/rocker/rocker_of_dpa.h
@@ -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_ */
diff --git a/hw/net/rocker/rocker_tlv.h b/hw/net/rocker/rocker_tlv.h
index dd28d0844..e3c4ab679 100644
--- a/hw/net/rocker/rocker_tlv.h
+++ b/hw/net/rocker/rocker_tlv.h
@@ -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,
diff --git a/hw/net/rocker/rocker_world.h b/hw/net/rocker/rocker_world.h
index 44f1fe3e1..58ade4733 100644
--- a/hw/net/rocker/rocker_world.h
+++ b/hw/net/rocker/rocker_world.h
@@ -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_ */
diff --git a/hw/net/rtl8139.c b/hw/net/rtl8139.c
index 3345bc6b5..1e5ec149f 100644
--- a/hw/net/rtl8139.c
+++ b/hw/net/rtl8139.c
@@ -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,
diff --git a/hw/net/smc91c111.c b/hw/net/smc91c111.c
index 3b16dcf5a..21c1b8f54 100644
--- a/hw/net/smc91c111.c
+++ b/hw/net/smc91c111.c
@@ -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,
diff --git a/hw/net/spapr_llan.c b/hw/net/spapr_llan.c
index b273eda93..a647f25d9 100644
--- a/hw/net/spapr_llan.c
+++ b/hw/net/spapr_llan.c
@@ -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()
},
diff --git a/hw/net/stellaris_enet.c b/hw/net/stellaris_enet.c
index 957730e02..688089494 100644
--- a/hw/net/stellaris_enet.c
+++ b/hw/net/stellaris_enet.c
@@ -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
index 8d38d7724..000000000
--- a/hw/net/trace-events
+++ /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"
diff --git a/hw/net/vhost_net.c b/hw/net/vhost_net.c
index f2d49ad7e..6e1032fc1 100644
--- a/hw/net/vhost_net.c
+++ b/hw/net/vhost_net.c
@@ -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;
diff --git a/hw/net/virtio-net.c b/hw/net/virtio-net.c
index 01f135155..8aaa10380 100644
--- a/hw/net/virtio-net.c
+++ b/hw/net/virtio-net.c
@@ -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;
diff --git a/hw/net/vmware_utils.h b/hw/net/vmware_utils.h
index 550060170..c0dbb2ff4 100644
--- a/hw/net/vmware_utils.h
+++ b/hw/net/vmware_utils.h
@@ -26,104 +26,97 @@
*
*/
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 */
diff --git a/hw/net/vmxnet3.c b/hw/net/vmxnet3.c
index 90f694366..20f26b7d8 100644
--- a/hw/net/vmxnet3.c
+++ b/hw/net/vmxnet3.c
@@ -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
@@ -74,54 +74,54 @@
#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;
diff --git a/hw/net/vmxnet3.h b/hw/net/vmxnet3.h
index f9352c4a2..f7006afe9 100644
--- a/hw/net/vmxnet3.h
+++ b/hw/net/vmxnet3.h
@@ -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 */
diff --git a/hw/net/vmxnet_debug.h b/hw/net/vmxnet_debug.h
index cb50aa95d..96495dbb1 100644
--- a/hw/net/vmxnet_debug.h
+++ b/hw/net/vmxnet_debug.h
@@ -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"
@@ -142,4 +142,7 @@
} \
} 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
index 000000000..21bb46e68
--- /dev/null
+++ b/hw/net/vmxnet_rx_pkt.c
@@ -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
index 000000000..0a45c1ba0
--- /dev/null
+++ b/hw/net/vmxnet_rx_pkt.h
@@ -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
diff --git a/hw/net/net_tx_pkt.c b/hw/net/vmxnet_tx_pkt.c
index 20b25496e..91e1e08fd 100644
--- a/hw/net/net_tx_pkt.c
+++ b/hw/net/vmxnet_tx_pkt.c
@@ -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)
*
@@ -16,24 +16,24 @@
*/
#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
index 000000000..f51e98ad9
--- /dev/null
+++ b/hw/net/vmxnet_tx_pkt.h
@@ -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
diff --git a/hw/net/xen_nic.c b/hw/net/xen_nic.c
index 6856b5299..7281730d9 100644
--- a/hw/net/xen_nic.c
+++ b/hw/net/xen_nic.c
@@ -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,
};
diff --git a/hw/net/xgmac.c b/hw/net/xgmac.c
index 46b1aa17f..0c5f793bd 100644
--- a/hw/net/xgmac.c
+++ b/hw/net/xgmac.c
@@ -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,
};
diff --git a/hw/net/xilinx_axienet.c b/hw/net/xilinx_axienet.c
index b6701844d..de23ab5dc 100644
--- a/hw/net/xilinx_axienet.c
+++ b/hw/net/xilinx_axienet.c
@@ -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,
};
diff --git a/hw/net/xilinx_ethlite.c b/hw/net/xilinx_ethlite.c
index 35de353b7..bc846e709 100644
--- a/hw/net/xilinx_ethlite.c
+++ b/hw/net/xilinx_ethlite.c
@@ -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,
diff --git a/hw/nvram/fw_cfg.c b/hw/nvram/fw_cfg.c
index 6a68e594d..999f48028 100644
--- a/hw/nvram/fw_cfg.c
+++ b/hw/nvram/fw_cfg.c
@@ -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,
};
diff --git a/hw/nvram/spapr_nvram.c b/hw/nvram/spapr_nvram.c
index 4de5f705d..802636ef3 100644
--- a/hw/nvram/spapr_nvram.c
+++ b/hw/nvram/spapr_nvram.c
@@ -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
index 1f1e05ab6..000000000
--- a/hw/nvram/trace-events
+++ /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)"
diff --git a/hw/pci-bridge/dec.h b/hw/pci-bridge/dec.h
index ae17ca736..17dc0c2b0 100644
--- a/hw/pci-bridge/dec.h
+++ b/hw/pci-bridge/dec.h
@@ -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"
diff --git a/hw/pci-bridge/ioh3420.c b/hw/pci-bridge/ioh3420.c
index c8b5ac420..0937fa34b 100644
--- a/hw/pci-bridge/ioh3420.c
+++ b/hw/pci-bridge/ioh3420.c
@@ -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:
+ */
diff --git a/hw/pci-bridge/pci_bridge_dev.c b/hw/pci-bridge/pci_bridge_dev.c
index 5dbd933cc..7b582e96a 100644
--- a/hw/pci-bridge/pci_bridge_dev.c
+++ b/hw/pci-bridge/pci_bridge_dev.c
@@ -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(),
diff --git a/hw/pci-bridge/pci_expander_bridge.c b/hw/pci-bridge/pci_expander_bridge.c
index 1cc598f7e..ba320bd85 100644
--- a/hw/pci-bridge/pci_expander_bridge.c
+++ b/hw/pci-bridge/pci_expander_bridge.c
@@ -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);
}
diff --git a/hw/pci-bridge/xio3130_downstream.c b/hw/pci-bridge/xio3130_downstream.c
index cef6e1325..cf1ee63ab 100644
--- a/hw/pci-bridge/xio3130_downstream.c
+++ b/hw/pci-bridge/xio3130_downstream.c
@@ -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:
+ */
diff --git a/hw/pci-bridge/xio3130_upstream.c b/hw/pci-bridge/xio3130_upstream.c
index 4ad0440aa..164ef58c4 100644
--- a/hw/pci-bridge/xio3130_upstream.c
+++ b/hw/pci-bridge/xio3130_upstream.c
@@ -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:
+ */
diff --git a/hw/pci-bridge/xio3130_upstream.h b/hw/pci-bridge/xio3130_upstream.h
index d0ab7577e..08c1d5f75 100644
--- a/hw/pci-bridge/xio3130_upstream.h
+++ b/hw/pci-bridge/xio3130_upstream.h
@@ -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 */
diff --git a/hw/pci-host/apb.c b/hw/pci-host/apb.c
index 653e71112..aaef7bb3a 100644
--- a/hw/pci-host/apb.c
+++ b/hw/pci-host/apb.c
@@ -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;
diff --git a/hw/pci-host/grackle.c b/hw/pci-host/grackle.c
index 2c8acdaac..8f9121615 100644
--- a/hw/pci-host/grackle.c
+++ b/hw/pci-host/grackle.c
@@ -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);
diff --git a/hw/pci-host/piix.c b/hw/pci-host/piix.c
index f9218aa95..df2b0e26f 100644
--- a/hw/pci-host/piix.c
+++ b/hw/pci-host/piix.c
@@ -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 = {
diff --git a/hw/pci-host/prep.c b/hw/pci-host/prep.c
index 5580293f9..487e32ecb 100644
--- a/hw/pci-host/prep.c
+++ b/hw/pci-host/prep.c
@@ -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);
}
diff --git a/hw/pci-host/q35.c b/hw/pci-host/q35.c
index 344f77b10..70f897e3a 100644
--- a/hw/pci-host/q35.c
+++ b/hw/pci-host/q35.c
@@ -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)
diff --git a/hw/pci-host/uninorth.c b/hw/pci-host/uninorth.c
index 7aac4d67a..15b105423 100644
--- a/hw/pci-host/uninorth.c
+++ b/hw/pci-host/uninorth.c
@@ -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)
diff --git a/hw/pci-host/versatile.c b/hw/pci-host/versatile.c
index 467cbb9cb..339ec2c50 100644
--- a/hw/pci-host/versatile.c
+++ b/hw/pci-host/versatile.c
@@ -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);
}
diff --git a/hw/pci/msi.c b/hw/pci/msi.c
index a87b2278a..a87ef4d75 100644
--- a/hw/pci/msi.c
+++ b/hw/pci/msi.c
@@ -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)
diff --git a/hw/pci/msix.c b/hw/pci/msix.c
index 0ec1cb14f..b75f0e9c4 100644
--- a/hw/pci/msix.c
+++ b/hw/pci/msix.c
@@ -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);
}
diff --git a/hw/pci/pci.c b/hw/pci/pci.c
index 24fae1689..616f04c1f 100644
--- a/hw/pci/pci.c
+++ b/hw/pci/pci.c
@@ -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,
diff --git a/hw/pci/pcie.c b/hw/pci/pcie.c
index 99cfb4561..c85b4f7ae 100644
--- a/hw/pci/pcie.c
+++ b/hw/pci/pcie.c
@@ -43,18 +43,28 @@
/***************************************************************************
* 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);
-}
diff --git a/hw/pci/pcie_aer.c b/hw/pci/pcie_aer.c
index 048ce6a42..e2d4e68ba 100644
--- a/hw/pci/pcie_aer.c
+++ b/hw/pci/pcie_aer.c
@@ -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
index 2b9cf2440..000000000
--- a/hw/pci/trace-events
+++ /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"
diff --git a/hw/ppc/Makefile.objs b/hw/ppc/Makefile.objs
index 91a3420f4..c1ffc7771 100644
--- a/hw/ppc/Makefile.objs
+++ b/hw/ppc/Makefile.objs
@@ -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
diff --git a/hw/ppc/e500.c b/hw/ppc/e500.c
index 0cd534df5..ee1c60b82 100644
--- a/hw/ppc/e500.c
+++ b/hw/ppc/e500.c
@@ -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);
}
diff --git a/hw/ppc/e500.h b/hw/ppc/e500.h
index 70ba1d8f4..ef224ea5e 100644
--- a/hw/ppc/e500.h
+++ b/hw/ppc/e500.h
@@ -26,6 +26,4 @@ typedef struct PPCE500Params {
void ppce500_init(MachineState *machine, PPCE500Params *params);
-hwaddr booke206_page_size_to_tlb(uint64_t size);
-
#endif
diff --git a/hw/ppc/e500plat.c b/hw/ppc/e500plat.c
index 94b454551..b00565c3d 100644
--- a/hw/ppc/e500plat.c
+++ b/hw/ppc/e500plat.c
@@ -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"
diff --git a/hw/ppc/mac.h b/hw/ppc/mac.h
index 20cbddb4e..5764b86c2 100644
--- a/hw/ppc/mac.h
+++ b/hw/ppc/mac.h
@@ -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__) */
diff --git a/hw/ppc/mac_newworld.c b/hw/ppc/mac_newworld.c
index 7d2510658..32e88b378 100644
--- a/hw/ppc/mac_newworld.c
+++ b/hw/ppc/mac_newworld.c
@@ -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;
diff --git a/hw/ppc/mac_oldworld.c b/hw/ppc/mac_oldworld.c
index 447948746..a9bb1c27d 100644
--- a/hw/ppc/mac_oldworld.c
+++ b/hw/ppc/mac_oldworld.c
@@ -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");
}
diff --git a/hw/ppc/ppc.c b/hw/ppc/ppc.c
index 894586900..38ff2e159 100644
--- a/hw/ppc/ppc.c
+++ b/hw/ppc/ppc.c
@@ -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);
-}
diff --git a/hw/ppc/ppc405.h b/hw/ppc/ppc405.h
index c67febca2..1c5f04fae 100644
--- a/hw/ppc/ppc405.h
+++ b/hw/ppc/ppc405.h
@@ -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) */
diff --git a/hw/ppc/ppc4xx_devs.c b/hw/ppc/ppc4xx_devs.c
index e7f413e49..7d59018fc 100644
--- a/hw/ppc/ppc4xx_devs.c
+++ b/hw/ppc/ppc4xx_devs.c
@@ -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"
diff --git a/hw/ppc/ppce500_spin.c b/hw/ppc/ppce500_spin.c
index 22c584eb8..76bd78bfd 100644
--- a/hw/ppc/ppce500_spin.c
+++ b/hw/ppc/ppce500_spin.c
@@ -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;
diff --git a/hw/ppc/prep.c b/hw/ppc/prep.c
index 054af1e8b..3ffb85e60 100644
--- a/hw/ppc/prep.c
+++ b/hw/ppc/prep.c
@@ -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");
}
diff --git a/hw/ppc/spapr.c b/hw/ppc/spapr.c
index 30d6800ab..b69995e0d 100644
--- a/hw/ppc/spapr.c
+++ b/hw/ppc/spapr.c
@@ -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
index bcb483dbe..000000000
--- a/hw/ppc/spapr_cpu_core.c
+++ /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)
diff --git a/hw/ppc/spapr_drc.c b/hw/ppc/spapr_drc.c
index 26a067951..1f5f1d790 100644
--- a/hw/ppc/spapr_drc.c
+++ b/hw/ppc/spapr_drc.c
@@ -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) {
diff --git a/hw/ppc/spapr_events.c b/hw/ppc/spapr_events.c
index b0668b34a..049fb1b32 100644
--- a/hw/ppc/spapr_events.c
+++ b/hw/ppc/spapr_events.c
@@ -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);
diff --git a/hw/ppc/spapr_hcall.c b/hw/ppc/spapr_hcall.c
index 73af112e1..8f40602a5 100644
--- a/hw/ppc/spapr_hcall.c
+++ b/hw/ppc/spapr_hcall.c
@@ -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) {
diff --git a/hw/ppc/spapr_iommu.c b/hw/ppc/spapr_iommu.c
index 6bc4d4db3..7dd458846 100644
--- a/hw/ppc/spapr_iommu.c
+++ b/hw/ppc/spapr_iommu.c
@@ -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);
diff --git a/hw/ppc/spapr_pci.c b/hw/ppc/spapr_pci.c
index 949c44fec..573e635bf 100644
--- a/hw/ppc/spapr_pci.c
+++ b/hw/ppc/spapr_pci.c
@@ -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;
}
diff --git a/hw/ppc/spapr_pci_vfio.c b/hw/ppc/spapr_pci_vfio.c
index 8448e0b02..cbd3d23c9 100644
--- a/hw/ppc/spapr_pci_vfio.c
+++ b/hw/ppc/spapr_pci_vfio.c
@@ -18,16 +18,15 @@
*/
#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)
diff --git a/hw/ppc/spapr_rtas.c b/hw/ppc/spapr_rtas.c
index dc058e512..f07325831 100644
--- a/hw/ppc/spapr_rtas.c
+++ b/hw/ppc/spapr_rtas.c
@@ -26,17 +26,14 @@
*/
#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
index 177dcffc9..000000000
--- a/hw/ppc/spapr_rtas_ddw.c
+++ /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)
diff --git a/hw/ppc/spapr_vio.c b/hw/ppc/spapr_vio.c
index f93244d7c..8aa021fde 100644
--- a/hw/ppc/spapr_vio.c
+++ b/hw/ppc/spapr_vio.c
@@ -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
index dfeab9308..000000000
--- a/hw/ppc/trace-events
+++ /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
diff --git a/hw/ppc/virtex_ml507.c b/hw/ppc/virtex_ml507.c
index b97d96685..b807a08c2 100644
--- a/hw/ppc/virtex_ml507.c
+++ b/hw/ppc/virtex_ml507.c
@@ -23,7 +23,6 @@
*/
#include "qemu/osdep.h"
-#include "cpu.h"
#include "hw/sysbus.h"
#include "hw/hw.h"
#include "hw/char/serial.h"
diff --git a/hw/s390x/Makefile.objs b/hw/s390x/Makefile.objs
index 41ac4ec32..220361782 100644
--- a/hw/s390x/Makefile.objs
+++ b/hw/s390x/Makefile.objs
@@ -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
index 28ea20440..000000000
--- a/hw/s390x/ccw-device.c
+++ /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
index 59ba01b6c..000000000
--- a/hw/s390x/ccw-device.h
+++ /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
index 9a7f7ee60..000000000
--- a/hw/s390x/css-bridge.c
+++ /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)
diff --git a/hw/s390x/css.c b/hw/s390x/css.c
index bb8e4be33..3a1d91958 100644
--- a/hw/s390x/css.c
+++ b/hw/s390x/css.c
@@ -10,14 +10,12 @@
*/
#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;
-}
diff --git a/include/hw/s390x/css.h b/hw/s390x/css.h
index 1da63e361..a320eea59 100644
--- a/include/hw/s390x/css.h
+++ b/hw/s390x/css.h
@@ -14,10 +14,9 @@
#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
diff --git a/hw/s390x/ipl.c b/hw/s390x/ipl.c
index 2e2664f22..3173dcfdf 100644
--- a/hw/s390x/ipl.c
+++ b/hw/s390x/ipl.c
@@ -30,24 +30,6 @@
#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;
}
diff --git a/hw/s390x/ipl.h b/hw/s390x/ipl.h
index c89109585..0bfb72b71 100644
--- a/hw/s390x/ipl.h
+++ b/hw/s390x/ipl.h
@@ -15,71 +15,11 @@
#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
diff --git a/hw/s390x/s390-pci-bus.c b/hw/s390x/s390-pci-bus.c
index 9c1c04e59..918b58543 100644
--- a/hw/s390x/s390-pci-bus.c
+++ b/hw/s390x/s390-pci-bus.c
@@ -12,15 +12,12 @@
*/
#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
@@ -31,19 +28,6 @@
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)
diff --git a/hw/s390x/s390-pci-bus.h b/hw/s390x/s390-pci-bus.h
index 4f564e02f..59fd5c958 100644
--- a/hw/s390x/s390-pci-bus.h
+++ b/hw/s390x/s390-pci-bus.h
@@ -14,38 +14,23 @@
#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
diff --git a/hw/s390x/s390-pci-inst.c b/hw/s390x/s390-pci-inst.c
index f069b110b..b28e7d14f 100644
--- a/hw/s390x/s390-pci-inst.c
+++ b/hw/s390x/s390-pci-inst.c
@@ -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;
}
diff --git a/hw/s390x/s390-pci-inst.h b/hw/s390x/s390-pci-inst.h
index 23f4bfa0e..70fa71395 100644
--- a/hw/s390x/s390-pci-inst.h
+++ b/hw/s390x/s390-pci-inst.h
@@ -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);
diff --git a/hw/s390x/s390-skeys.c b/hw/s390x/s390-skeys.c
index e2d4e1af7..6528ffed1 100644
--- a/hw/s390x/s390-skeys.c
+++ b/hw/s390x/s390-skeys.c
@@ -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)
diff --git a/hw/s390x/s390-virtio-ccw.c b/hw/s390x/s390-virtio-ccw.c
index 91d9cefbb..e3df9c78b 100644
--- a/hw/s390x/s390-virtio-ccw.c
+++ b/hw/s390x/s390-virtio-ccw.c
@@ -18,19 +18,17 @@
#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);
diff --git a/hw/s390x/s390-virtio.h b/hw/s390x/s390-virtio.h
index f588b80a6..ffd014cb5 100644
--- a/hw/s390x/s390-virtio.h
+++ b/hw/s390x/s390-virtio.h
@@ -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"
diff --git a/hw/s390x/sclp.c b/hw/s390x/sclp.c
index fca37f511..85dbe1b60 100644
--- a/hw/s390x/sclp.c
+++ b/hw/s390x/sclp.c
@@ -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);
diff --git a/hw/s390x/sclpquiesce.c b/hw/s390x/sclpquiesce.c
index 762cb184a..c0ecab9c3 100644
--- a/hw/s390x/sclpquiesce.c
+++ b/hw/s390x/sclpquiesce.c
@@ -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
index 84ea96487..000000000
--- a/hw/s390x/trace-events
+++ /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"
diff --git a/hw/s390x/virtio-ccw.c b/hw/s390x/virtio-ccw.c
index a554a24d0..d51642db0 100644
--- a/hw/s390x/virtio-ccw.c
+++ b/hw/s390x/virtio-ccw.c
@@ -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"
@@ -29,15 +28,35 @@
#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
diff --git a/hw/s390x/virtio-ccw.h b/hw/s390x/virtio-ccw.h
index 1c6bc8631..66c831ba8 100644
--- a/hw/s390x/virtio-ccw.h
+++ b/hw/s390x/virtio-ccw.h
@@ -13,21 +13,20 @@
#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);
diff --git a/hw/scsi/esp.c b/hw/scsi/esp.c
index 1f2f2d33d..baa0a2cfd 100644
--- a/hw/scsi/esp.c
+++ b/hw/scsi/esp.c
@@ -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),
diff --git a/hw/scsi/megasas.c b/hw/scsi/megasas.c
index e968302fd..a9ffc3268 100644
--- a/hw/scsi/megasas.c
+++ b/hw/scsi/megasas.c
@@ -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"
@@ -48,7 +48,11 @@
#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(),
diff --git a/hw/scsi/mfi.h b/hw/scsi/mfi.h
index e67a5c0b4..29d41775d 100644
--- a/hw/scsi/mfi.h
+++ b/hw/scsi/mfi.h
@@ -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 */
diff --git a/hw/scsi/mptsas.c b/hw/scsi/mptsas.c
index 0e0a22f69..be88e161a 100644
--- a/hw/scsi/mptsas.c
+++ b/hw/scsi/mptsas.c
@@ -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(),
};
diff --git a/hw/scsi/mptsas.h b/hw/scsi/mptsas.h
index 0436a3391..595f81fb5 100644
--- a/hw/scsi/mptsas.h
+++ b/hw/scsi/mptsas.h
@@ -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;
diff --git a/hw/scsi/scsi-bus.c b/hw/scsi/scsi-bus.c
index 297216dfc..ad6f398c3 100644
--- a/hw/scsi/scsi-bus.c
+++ b/hw/scsi/scsi-bus.c
@@ -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;
diff --git a/hw/scsi/scsi-disk.c b/hw/scsi/scsi-disk.c
index 836a1553e..c3ce54a20 100644
--- a/hw/scsi/scsi-disk.c
+++ b/hw/scsi/scsi-disk.c
@@ -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__
diff --git a/hw/scsi/scsi-generic.c b/hw/scsi/scsi-generic.c
index 7a588a7ad..c4ba9a485 100644
--- a/hw/scsi/scsi-generic.c
+++ b/hw/scsi/scsi-generic.c
@@ -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
index ed64858fe..000000000
--- a/hw/scsi/trace-events
+++ /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"
diff --git a/hw/scsi/vhost-scsi.c b/hw/scsi/vhost-scsi.c
index 5b2694615..9261d51da 100644
--- a/hw/scsi/vhost-scsi.c
+++ b/hw/scsi/vhost-scsi.c
@@ -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));
diff --git a/hw/scsi/virtio-scsi-dataplane.c b/hw/scsi/virtio-scsi-dataplane.c
index b173b9494..1a49f1e4b 100644
--- a/hw/scsi/virtio-scsi-dataplane.c
+++ b/hw/scsi/virtio-scsi-dataplane.c
@@ -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) */
diff --git a/hw/scsi/virtio-scsi.c b/hw/scsi/virtio-scsi.c
index ce57ef624..30415c6a9 100644
--- a/hw/scsi/virtio-scsi.c
+++ b/hw/scsi/virtio-scsi.c
@@ -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;
diff --git a/hw/scsi/vmw_pvscsi.c b/hw/scsi/vmw_pvscsi.c
index 5116f4ad6..2d7528d1d 100644
--- a/hw/scsi/vmw_pvscsi.c
+++ b/hw/scsi/vmw_pvscsi.c
@@ -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 = {
diff --git a/hw/sd/milkymist-memcard.c b/hw/sd/milkymist-memcard.c
index 1f2f0ed44..c04ff02fa 100644
--- a/hw/sd/milkymist-memcard.c
+++ b/hw/sd/milkymist-memcard.c
@@ -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"
diff --git a/hw/sd/pl181.c b/hw/sd/pl181.c
index 82c63a4fb..e87abb205 100644
--- a/hw/sd/pl181.c
+++ b/hw/sd/pl181.c
@@ -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,
};
diff --git a/hw/sd/sd.c b/hw/sd/sd.c
index 87c6dc108..b66e5d2db 100644
--- a/hw/sd/sd.c
+++ b/hw/sd/sd.c
@@ -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);
}
diff --git a/hw/sd/sdhci.c b/hw/sd/sdhci.c
index 01fbf228b..d28b5871f 100644
--- a/hw/sd/sdhci.c
+++ b/hw/sd/sdhci.c
@@ -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
diff --git a/hw/sd/ssi-sd.c b/hw/sd/ssi-sd.c
index 3ff0886dd..075e4ed5d 100644
--- a/hw/sd/ssi-sd.c
+++ b/hw/sd/ssi-sd.c
@@ -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
index b17e7ba44..000000000
--- a/hw/sd/trace-events
+++ /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"
diff --git a/hw/sh4/sh7750.c b/hw/sh4/sh7750.c
index 3132d559d..a1ea760f6 100644
--- a/hw/sh4/sh7750.c
+++ b/hw/sh4/sh7750.c
@@ -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
diff --git a/hw/sh4/sh7750_regnames.h b/hw/sh4/sh7750_regnames.h
index e3ba88636..7463709b4 100644
--- a/hw/sh4/sh7750_regnames.h
+++ b/hw/sh4/sh7750_regnames.h
@@ -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 */
diff --git a/hw/sh4/sh7750_regs.h b/hw/sh4/sh7750_regs.h
index 3e4554af3..534aa4840 100644
--- a/hw/sh4/sh7750_regs.h
+++ b/hw/sh4/sh7750_regs.h
@@ -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
diff --git a/hw/sh4/sh_pci.c b/hw/sh4/sh_pci.c
index 1747628f3..e820a3230 100644
--- a/hw/sh4/sh_pci.c
+++ b/hw/sh4/sh_pci.c
@@ -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:
diff --git a/hw/smbios/Makefile.objs b/hw/smbios/Makefile.objs
index c3d375360..f69a92f96 100644
--- a/hw/smbios/Makefile.objs
+++ b/hw/smbios/Makefile.objs
@@ -1,2 +1 @@
common-obj-$(CONFIG_SMBIOS) += smbios.o
-common-obj-$(call land,$(CONFIG_SMBIOS),$(CONFIG_IPMI)) += smbios_type_38.o
diff --git a/hw/smbios/smbios.c b/hw/smbios/smbios.c
index 74c710292..cb8a11110 100644
--- a/hw/smbios/smbios.c
+++ b/hw/smbios/smbios.c
@@ -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
index 68b8b72e0..000000000
--- a/hw/smbios/smbios_build.h
+++ /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
index 56e8609c0..000000000
--- a/hw/smbios/smbios_type_38.c
+++ /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);
- }
-}
diff --git a/hw/sparc/leon3.c b/hw/sparc/leon3.c
index 6e1647841..dbae41f3a 100644
--- a/hw/sparc/leon3.c
+++ b/hw/sparc/leon3.c
@@ -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",
diff --git a/hw/sparc/sun4m.c b/hw/sparc/sun4m.c
index 478fda820..7bfc00abc 100644
--- a/hw/sparc/sun4m.c
+++ b/hw/sparc/sun4m.c
@@ -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
index 30fb0373e..000000000
--- a/hw/sparc/trace-events
+++ /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"
diff --git a/hw/ssi/Makefile.objs b/hw/ssi/Makefile.objs
index c79a8dcd8..9555825ac 100644
--- a/hw/ssi/Makefile.objs
+++ b/hw/ssi/Makefile.objs
@@ -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
index d319e04a2..000000000
--- a/hw/ssi/aspeed_smc.c
+++ /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
index 422619981..000000000
--- a/hw/ssi/imx_spi.c
+++ /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)
diff --git a/hw/ssi/pl022.c b/hw/ssi/pl022.c
index c1368018e..564a0d36e 100644
--- a/hw/ssi/pl022.c
+++ b/hw/ssi/pl022.c
@@ -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
diff --git a/hw/ssi/ssi.c b/hw/ssi/ssi.c
index 7eaaf565f..9791c0d94 100644
--- a/hw/ssi/ssi.c
+++ b/hw/ssi/ssi.c
@@ -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;
diff --git a/hw/timer/Makefile.objs b/hw/timer/Makefile.objs
index 7ba8c23c7..003c14fa2 100644
--- a/hw/timer/Makefile.objs
+++ b/hw/timer/Makefile.objs
@@ -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
diff --git a/hw/timer/allwinner-a10-pit.c b/hw/timer/allwinner-a10-pit.c
index 3385e5dc3..51cdc98f3 100644
--- a/hw/timer/allwinner-a10-pit.c
+++ b/hw/timer/allwinner-a10-pit.c
@@ -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)
{
diff --git a/hw/timer/arm_timer.c b/hw/timer/arm_timer.c
index 111a16db3..f1ede5f53 100644
--- a/hw/timer/arm_timer.c
+++ b/hw/timer/arm_timer.c
@@ -14,7 +14,6 @@
#include "hw/qdev.h"
#include "hw/ptimer.h"
#include "qemu/main-loop.h"
-#include "qemu/log.h"
/* Common timer implementation. */
diff --git a/hw/timer/aspeed_timer.c b/hw/timer/aspeed_timer.c
index 9b70ee09b..ebec35935 100644
--- a/hw/timer/aspeed_timer.c
+++ b/hw/timer/aspeed_timer.c
@@ -10,12 +10,13 @@
*/
#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()
}
diff --git a/hw/timer/digic-timer.c b/hw/timer/digic-timer.c
index 0f21faf87..5b97e1e1a 100644
--- a/hw/timer/digic-timer.c
+++ b/hw/timer/digic-timer.c
@@ -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"
diff --git a/hw/timer/imx_epit.c b/hw/timer/imx_epit.c
index eddf3481e..f5836e21f 100644
--- a/hw/timer/imx_epit.c
+++ b/hw/timer/imx_epit.c
@@ -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
diff --git a/hw/timer/imx_gpt.c b/hw/timer/imx_gpt.c
index 82bc73cb8..ab2e213a1 100644
--- a/hw/timer/imx_gpt.c
+++ b/hw/timer/imx_gpt.c
@@ -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)
diff --git a/hw/timer/lm32_timer.c b/hw/timer/lm32_timer.c
index e45a65bb9..3198355aa 100644
--- a/hw/timer/lm32_timer.c
+++ b/hw/timer/lm32_timer.c
@@ -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,
};
diff --git a/hw/timer/mc146818rtc.c b/hw/timer/mc146818rtc.c
index ea625f25c..2ac0fd3e4 100644
--- a/hw/timer/mc146818rtc.c
+++ b/hw/timer/mc146818rtc.c
@@ -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);
diff --git a/hw/timer/milkymist-sysctl.c b/hw/timer/milkymist-sysctl.c
index 21948328c..5f2948037 100644
--- a/hw/timer/milkymist-sysctl.c
+++ b/hw/timer/milkymist-sysctl.c
@@ -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
index 369888947..000000000
--- a/hw/timer/mips_gictimer.c
+++ /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;
-}
diff --git a/hw/timer/omap_gptimer.c b/hw/timer/omap_gptimer.c
index 5e3e8a6d7..3a4386304 100644
--- a/hw/timer/omap_gptimer.c
+++ b/hw/timer/omap_gptimer.c
@@ -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);
diff --git a/hw/timer/pl031.c b/hw/timer/pl031.c
index dbbeb9b16..38e0cb5ad 100644
--- a/hw/timer/pl031.c
+++ b/hw/timer/pl031.c
@@ -16,7 +16,6 @@
#include "qemu/timer.h"
#include "sysemu/sysemu.h"
#include "qemu/cutils.h"
-#include "qemu/log.h"
//#define DEBUG_PL031
diff --git a/hw/timer/stm32f2xx_timer.c b/hw/timer/stm32f2xx_timer.c
index bf0fb288c..55dacbbe3 100644
--- a/hw/timer/stm32f2xx_timer.c
+++ b/hw/timer/stm32f2xx_timer.c
@@ -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
index 3495c41c1..000000000
--- a/hw/timer/trace-events
+++ /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
diff --git a/hw/tpm/tpm_util.h b/hw/tpm/tpm_util.h
index df76245e6..e7f354a52 100644
--- a/hw/tpm/tpm_util.h
+++ b/hw/tpm/tpm_util.h
@@ -18,12 +18,11 @@
* 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 */
diff --git a/hw/usb/Makefile.objs b/hw/usb/Makefile.objs
index 98b5c9d27..2717027d3 100644
--- a/hw/usb/Makefile.objs
+++ b/hw/usb/Makefile.objs
@@ -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
diff --git a/hw/usb/bus.c b/hw/usb/bus.c
index 25913ad48..16c3461d9 100644
--- a/hw/usb/bus.c
+++ b/hw/usb/bus.c
@@ -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,
diff --git a/hw/usb/desc.c b/hw/usb/desc.c
index 5e0e1d157..adb026e43 100644
--- a/hw/usb/desc.c
+++ b/hw/usb/desc.c
@@ -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)
diff --git a/hw/usb/dev-mtp.c b/hw/usb/dev-mtp.c
index 1be85ae75..bda84a64b 100644
--- a/hw/usb/dev-mtp.c
+++ b/hw/usb/dev-mtp.c
@@ -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);
diff --git a/hw/usb/dev-network.c b/hw/usb/dev-network.c
index c0f1193ba..74306b58e 100644
--- a/hw/usb/dev-network.c
+++ b/hw/usb/dev-network.c
@@ -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;
diff --git a/hw/usb/dev-storage.c b/hw/usb/dev-storage.c
index c607f7606..248a58045 100644
--- a/hw/usb/dev-storage.c
+++ b/hw/usb/dev-storage.c
@@ -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 = {
diff --git a/hw/usb/dev-uas.c b/hw/usb/dev-uas.c
index 3a8ff18b1..0678b1b05 100644
--- a/hw/usb/dev-uas.c
+++ b/hw/usb/dev-uas.c
@@ -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;
diff --git a/hw/usb/hcd-ehci.c b/hw/usb/hcd-ehci.c
index b093db729..43a8f7abc 100644
--- a/hw/usb/hcd-ehci.c
+++ b/hw/usb/hcd-ehci.c
@@ -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)
diff --git a/hw/usb/hcd-ehci.h b/hw/usb/hcd-ehci.h
index 3fd703865..30218423c 100644
--- a/hw/usb/hcd-ehci.h
+++ b/hw/usb/hcd-ehci.h
@@ -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"
diff --git a/hw/usb/hcd-ohci.c b/hw/usb/hcd-ohci.c
index fa5703832..16d9ff7b4 100644
--- a/hw/usb/hcd-ohci.c
+++ b/hw/usb/hcd-ohci.c
@@ -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;
diff --git a/hw/usb/hcd-xhci.c b/hw/usb/hcd-xhci.c
index 188f95416..43ba61599 100644
--- a/hw/usb/hcd-xhci.c
+++ b/hw/usb/hcd-xhci.c
@@ -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,
diff --git a/hw/usb/host-libusb.c b/hw/usb/host-libusb.c
index e94672c15..6458a9448 100644
--- a/hw/usb/host-libusb.c
+++ b/hw/usb/host-libusb.c
@@ -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);
}
diff --git a/hw/usb/redirect.c b/hw/usb/redirect.c
index 444672a00..8d8054037 100644
--- a/hw/usb/redirect.c
+++ b/hw/usb/redirect.c
@@ -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
index 2d42fd45d..000000000
--- a/hw/usb/trace-events
+++ /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
index 174d715e3..000000000
--- a/hw/usb/xen-usb.c
+++ /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
diff --git a/hw/vfio/Makefile.objs b/hw/vfio/Makefile.objs
index c25e32b02..ceddbb8f9 100644
--- a/hw/vfio/Makefile.objs
+++ b/hw/vfio/Makefile.objs
@@ -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
diff --git a/hw/vfio/common.c b/hw/vfio/common.c
index b313e7c2c..e1927a5b9 100644
--- a/hw/vfio/common.c
+++ b/hw/vfio/common.c
@@ -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)
*/
diff --git a/hw/vfio/pci-quirks.c b/hw/vfio/pci-quirks.c
index bec694c8d..6624905e1 100644
--- a/hw/vfio/pci-quirks.c
+++ b/hw/vfio/pci-quirks.c
@@ -11,12 +11,9 @@
*/
#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)
diff --git a/hw/vfio/pci.c b/hw/vfio/pci.c
index 7bfa17ce3..d091d8cf0 100644
--- a/hw/vfio/pci.c
+++ b/hw/vfio/pci.c
@@ -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),
diff --git a/hw/vfio/pci.h b/hw/vfio/pci.h
index 7d482d9d2..72174b3dd 100644
--- a/hw/vfio/pci.h
+++ b/hw/vfio/pci.h
@@ -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 */
diff --git a/hw/vfio/platform.c b/hw/vfio/platform.c
index a559e7b65..1798a00a3 100644
--- a/hw/vfio/platform.c
+++ b/hw/vfio/platform.c
@@ -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
index 7443d348d..000000000
--- a/hw/vfio/spapr.c
+++ /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
index da133221d..000000000
--- a/hw/vfio/trace-events
+++ /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
index 55184d33b..000000000
--- a/hw/virtio/trace-events
+++ /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"
-
diff --git a/hw/virtio/vhost-backend.c b/hw/virtio/vhost-backend.c
index 7681f152f..b35890289 100644
--- a/hw/virtio/vhost-backend.c
+++ b/hw/virtio/vhost-backend.c
@@ -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,
diff --git a/hw/virtio/vhost-user.c b/hw/virtio/vhost-user.c
index b57454a4b..5914e8510 100644
--- a/hw/virtio/vhost-user.c
+++ b/hw/virtio/vhost-user.c
@@ -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;
}
diff --git a/hw/virtio/vhost.c b/hw/virtio/vhost.c
index 3d0c807d0..440071815 100644
--- a/hw/virtio/vhost.c
+++ b/hw/virtio/vhost.c
@@ -27,18 +27,6 @@
#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;
-}
diff --git a/hw/virtio/virtio-balloon.c b/hw/virtio/virtio-balloon.c
index 5af429a58..9dbe68179 100644
--- a/hw/virtio/virtio-balloon.c
+++ b/hw/virtio/virtio-balloon.c
@@ -27,6 +27,10 @@
#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;
diff --git a/hw/virtio/virtio-bus.c b/hw/virtio/virtio-bus.c
index a85b7c8ab..574f0e23f 100644
--- a/hw/virtio/virtio-bus.c
+++ b/hw/virtio/virtio-bus.c
@@ -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);
diff --git a/hw/virtio/virtio-mmio.c b/hw/virtio/virtio-mmio.c
index 13798b3cb..d4cd91f8c 100644
--- a/hw/virtio/virtio-mmio.c
+++ b/hw/virtio/virtio-mmio.c
@@ -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 = {
diff --git a/hw/virtio/virtio-pci.c b/hw/virtio/virtio-pci.c
index 755f9218b..bfedbbf17 100644
--- a/hw/virtio/virtio-pci.c
+++ b/hw/virtio/virtio-pci.c
@@ -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 = {
diff --git a/hw/virtio/virtio-pci.h b/hw/virtio/virtio-pci.h
index 25fbf8a37..e4548c2f9 100644
--- a/hw/virtio/virtio-pci.h
+++ b/hw/virtio/virtio-pci.h
@@ -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.
diff --git a/hw/virtio/virtio-rng.c b/hw/virtio/virtio-rng.c
index cd8ca1017..6b991a764 100644
--- a/hw/virtio/virtio-rng.c
+++ b/hw/virtio/virtio-rng.c
@@ -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;
diff --git a/hw/virtio/virtio.c b/hw/virtio/virtio.c
index 74c085c74..8ed260a61 100644
--- a/hw/virtio/virtio.c
+++ b/hw/virtio/virtio.c
@@ -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,
diff --git a/hw/watchdog/watchdog.c b/hw/watchdog/watchdog.c
index 2aeaf1fbc..bbf3646ba 100644
--- a/hw/watchdog/watchdog.c
+++ b/hw/watchdog/watchdog.c
@@ -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;
}
}
diff --git a/hw/watchdog/wdt_diag288.c b/hw/watchdog/wdt_diag288.c
index a7b64e2c4..f54a35a0e 100644
--- a/hw/watchdog/wdt_diag288.c
+++ b/hw/watchdog/wdt_diag288.c
@@ -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,
diff --git a/hw/xen/xen-host-pci-device.h b/hw/xen/xen-host-pci-device.h
index 4d8d34ecb..6acf36e13 100644
--- a/hw/xen/xen-host-pci-device.h
+++ b/hw/xen/xen-host-pci-device.h
@@ -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_ */
diff --git a/hw/xen/xen_backend.c b/hw/xen/xen_backend.c
index 69a238817..60575ad38 100644
--- a/hw/xen/xen_backend.c
+++ b/hw/xen/xen_backend.c
@@ -23,20 +23,16 @@
*/
#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);
diff --git a/hw/xen/xen_devconfig.c b/hw/xen/xen_devconfig.c
index b7d290df6..1f30fe4f5 100644
--- a/hw/xen/xen_devconfig.c
+++ b/hw/xen/xen_devconfig.c
@@ -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;
}
diff --git a/hw/xen/xen_pt.h b/hw/xen/xen_pt.h
index 191d9caea..c2f8e1fc2 100644
--- a/hw/xen/xen_pt.h
+++ b/hw/xen/xen_pt.h
@@ -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 */
diff --git a/hw/xen/xen_pt_config_init.c b/hw/xen/xen_pt_config_init.c
index 6f18366f6..9869ffda0 100644
--- a/hw/xen/xen_pt_config_init.c
+++ b/hw/xen/xen_pt_config_init.c
@@ -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);
diff --git a/hw/xen/xen_pt_msi.c b/hw/xen/xen_pt_msi.c
index 62add0639..9a16f2bff 100644
--- a/hw/xen/xen_pt_msi.c
+++ b/hw/xen/xen_pt_msi.c
@@ -10,6 +10,7 @@
*/
#include "qemu/osdep.h"
+#include <sys/mman.h>
#include "hw/xen/xen_backend.h"
#include "xen_pt.h"
diff --git a/hw/xenpv/xen_domainbuild.h b/hw/xenpv/xen_domainbuild.h
index 652d9b410..29a91ea7b 100644
--- a/hw/xenpv/xen_domainbuild.h
+++ b/hw/xenpv/xen_domainbuild.h
@@ -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"
diff --git a/hw/xenpv/xen_machine_pv.c b/hw/xenpv/xen_machine_pv.c
index 79aef4ecc..fc1353599 100644
--- a/hw/xenpv/xen_machine_pv.c
+++ b/hw/xenpv/xen_machine_pv.c
@@ -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 */
diff --git a/hw/xtensa/bootparam.h b/hw/xtensa/bootparam.h
index ade7891ec..955f4e86e 100644
--- a/hw/xtensa/bootparam.h
+++ b/hw/xtensa/bootparam.h
@@ -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) */
diff --git a/hw/xtensa/pic_cpu.c b/hw/xtensa/pic_cpu.c
index 2bed64f15..c835bd009 100644
--- a/hw/xtensa/pic_cpu.c
+++ b/hw/xtensa/pic_cpu.c
@@ -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)
diff --git a/hw/xtensa/xtfpga.c b/hw/xtensa/xtfpga.c
index ac7594948..2d117369a 100644
--- a/hw/xtensa/xtfpga.c
+++ b/hw/xtensa/xtfpga.c
@@ -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);
diff --git a/include/block/aio.h b/include/block/aio.h
index 173c1ed40..88a64eeb3 100644
--- a/include/block/aio.h
+++ b/include/block/aio.h
@@ -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
diff --git a/include/block/block.h b/include/block/block.h
index 11c162d59..3a731377d 100644
--- a/include/block/block.h
+++ b/include/block/block.h
@@ -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
diff --git a/include/block/block_int.h b/include/block/block_int.h
index 1e939de4f..10d87595b 100644
--- a/include/block/block_int.h
+++ b/include/block/block_int.h
@@ -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"
@@ -37,12 +38,12 @@
#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);
diff --git a/include/block/blockjob.h b/include/block/blockjob.h
index 4ddb4ae2e..8bedc4936 100644
--- a/include/block/blockjob.h
+++ b/include/block/blockjob.h
@@ -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);
diff --git a/include/block/dirty-bitmap.h b/include/block/dirty-bitmap.h
index ee3388f90..80afe603f 100644
--- a/include/block/dirty-bitmap.h
+++ b/include/block/dirty-bitmap.h
@@ -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);
diff --git a/include/block/nbd.h b/include/block/nbd.h
index 1897557a9..fde4421e5 100644
--- a/include/block/nbd.h
+++ b/include/block/nbd.h
@@ -25,20 +25,19 @@
#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,
diff --git a/include/block/scsi.h b/include/block/scsi.h
index cdf0a58a0..a311341e6 100644
--- a/include/block/scsi.h
+++ b/include/block/scsi.h
@@ -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
@@ -49,17 +48,13 @@
#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
@@ -67,12 +62,10 @@
#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
diff --git a/include/block/thread-pool.h b/include/block/thread-pool.h
index 7dd7d730a..42eb5e842 100644
--- a/include/block/thread-pool.h
+++ b/include/block/thread-pool.h
@@ -16,7 +16,7 @@
*/
#ifndef QEMU_THREAD_POOL_H
-#define QEMU_THREAD_POOL_H
+#define QEMU_THREAD_POOL_H 1
#include "block/block.h"
diff --git a/include/block/throttle-groups.h b/include/block/throttle-groups.h
index d983d3407..aba28f30b 100644
--- a/include/block/throttle-groups.h
+++ b/include/block/throttle-groups.h
@@ -28,19 +28,18 @@
#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);
diff --git a/include/crypto/aes.h b/include/crypto/aes.h
index 12fb321b8..a006da222 100644
--- a/include/crypto/aes.h
+++ b/include/crypto/aes.h
@@ -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);
diff --git a/include/crypto/afsplit.h b/include/crypto/afsplit.h
index 7dd21f0a6..4cc4ca4b3 100644
--- a/include/crypto/afsplit.h
+++ b/include/crypto/afsplit.h
@@ -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__ */
diff --git a/include/crypto/block.h b/include/crypto/block.h
index b6971de92..a21e11ff8 100644
--- a/include/crypto/block.h
+++ b/include/crypto/block.h
@@ -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__ */
diff --git a/include/crypto/cipher.h b/include/crypto/cipher.h
index 376654dcd..d770c4835 100644
--- a/include/crypto/cipher.h
+++ b/include/crypto/cipher.h
@@ -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__ */
diff --git a/include/crypto/desrfb.h b/include/crypto/desrfb.h
index 7ca596c38..773667ee7 100644
--- a/include/crypto/desrfb.h
+++ b/include/crypto/desrfb.h
@@ -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 -
*
diff --git a/include/crypto/hash.h b/include/crypto/hash.h
index ca3267f3d..f38caed66 100644
--- a/include/crypto/hash.h
+++ b/include/crypto/hash.h
@@ -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__ */
diff --git a/include/crypto/init.h b/include/crypto/init.h
index 04c1edf77..2513ed098 100644
--- a/include/crypto/init.h
+++ b/include/crypto/init.h
@@ -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__ */
diff --git a/include/crypto/ivgen.h b/include/crypto/ivgen.h
index 0350cd2a9..09cdb6fcd 100644
--- a/include/crypto/ivgen.h
+++ b/include/crypto/ivgen.h
@@ -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__ */
diff --git a/include/crypto/pbkdf.h b/include/crypto/pbkdf.h
index e9e4ceca8..58a1fe62a 100644
--- a/include/crypto/pbkdf.h
+++ b/include/crypto/pbkdf.h
@@ -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__ */
diff --git a/include/crypto/random.h b/include/crypto/random.h
index a10135320..f9308f464 100644
--- a/include/crypto/random.h
+++ b/include/crypto/random.h
@@ -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__ */
diff --git a/include/crypto/secret.h b/include/crypto/secret.h
index 07a963e79..b7392c6ba 100644
--- a/include/crypto/secret.h
+++ b/include/crypto/secret.h
@@ -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__ */
diff --git a/include/crypto/tlscreds.h b/include/crypto/tlscreds.h
index ad47d88be..8e2babd53 100644
--- a/include/crypto/tlscreds.h
+++ b/include/crypto/tlscreds.h
@@ -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__ */
+
diff --git a/include/crypto/tlscredsanon.h b/include/crypto/tlscredsanon.h
index 4d6b7e4d2..d3976b84b 100644
--- a/include/crypto/tlscredsanon.h
+++ b/include/crypto/tlscredsanon.h
@@ -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__ */
+
diff --git a/include/crypto/tlscredsx509.h b/include/crypto/tlscredsx509.h
index 66ad6a748..25796d7de 100644
--- a/include/crypto/tlscredsx509.h
+++ b/include/crypto/tlscredsx509.h
@@ -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__ */
+
diff --git a/include/crypto/tlssession.h b/include/crypto/tlssession.h
index 1c7414e4f..c1bad9e4f 100644
--- a/include/crypto/tlssession.h
+++ b/include/crypto/tlssession.h
@@ -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__ */
diff --git a/include/crypto/xts.h b/include/crypto/xts.h
index da32ab82b..c2924d8ba 100644
--- a/include/crypto/xts.h
+++ b/include/crypto/xts.h
@@ -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_ */
diff --git a/include/disas/bfd.h b/include/disas/bfd.h
index 8a3488c2c..a112e9c8c 100644
--- a/include/disas/bfd.h
+++ b/include/disas/bfd.h
@@ -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) */
diff --git a/include/disas/disas.h b/include/disas/disas.h
index e549ca24a..2b9293b62 100644
--- a/include/disas/disas.h
+++ b/include/disas/disas.h
@@ -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 */
diff --git a/include/elf.h b/include/elf.h
index 1c2975dc8..28d448bbc 100644
--- a/include/elf.h
+++ b/include/elf.h
@@ -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 */
diff --git a/include/exec/address-spaces.h b/include/exec/address-spaces.h
index db8bfa9a9..3d12cddee 100644
--- a/include/exec/address-spaces.h
+++ b/include/exec/address-spaces.h
@@ -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
diff --git a/include/exec/cpu-all.h b/include/exec/cpu-all.h
index b6a705982..08e5093d0 100644
--- a/include/exec/cpu-all.h
+++ b/include/exec/cpu-all.h
@@ -34,9 +34,14 @@
/* 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 */
diff --git a/include/exec/cpu-common.h b/include/exec/cpu-common.h
index 952bcfeb4..9e839e50c 100644
--- a/include/exec/cpu-common.h
+++ b/include/exec/cpu-common.h
@@ -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 */
diff --git a/include/exec/cpu-defs.h b/include/exec/cpu-defs.h
index 5f4e30363..854e7e356 100644
--- a/include/exec/cpu-defs.h
+++ b/include/exec/cpu-defs.h
@@ -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
diff --git a/include/exec/cpu_ldst_template.h b/include/exec/cpu_ldst_template.h
index eaf69a1ad..3091c0003 100644
--- a/include/exec/cpu_ldst_template.h
+++ b/include/exec/cpu_ldst_template.h
@@ -23,13 +23,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/>.
*/
-
-#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;
diff --git a/include/exec/cpu_ldst_useronly_template.h b/include/exec/cpu_ldst_useronly_template.h
index b1378bfae..040b14743 100644
--- a/include/exec/cpu_ldst_useronly_template.h
+++ b/include/exec/cpu_ldst_useronly_template.h
@@ -22,13 +22,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/>.
*/
-
-#if !defined(CODE_ACCESS)
-#include "trace.h"
-#endif
-
-#include "trace/mem.h"
-
#if DATA_SIZE == 8
#define SUFFIX q
#define USUFFIX q
@@ -60,11 +53,6 @@
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);
}
diff --git a/include/exec/exec-all.h b/include/exec/exec-all.h
index d008296c1..736209505 100644
--- a/include/exec/exec-all.h
+++ b/include/exec/exec-all.h
@@ -17,11 +17,10 @@
* 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
diff --git a/include/exec/gdbstub.h b/include/exec/gdbstub.h
index f9708bbcd..d9e8cf771 100644
--- a/include/exec/gdbstub.h
+++ b/include/exec/gdbstub.h
@@ -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 *);
diff --git a/include/exec/gen-icount.h b/include/exec/gen-icount.h
index 050de59b3..05d89d358 100644
--- a/include/exec/gen-icount.h
+++ b/include/exec/gen-icount.h
@@ -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)
diff --git a/include/exec/helper-gen.h b/include/exec/helper-gen.h
index 8239ffc77..0d0da3aeb 100644
--- a/include/exec/helper-gen.h
+++ b/include/exec/helper-gen.h
@@ -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)) \
diff --git a/include/exec/helper-head.h b/include/exec/helper-head.h
index 1cfc43b9f..ec790432d 100644
--- a/include/exec/helper-head.h
+++ b/include/exec/helper-head.h
@@ -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)
@@ -32,9 +33,17 @@
#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
@@ -44,24 +53,13 @@
#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
@@ -132,4 +130,4 @@
/* 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 */
diff --git a/include/exec/helper-proto.h b/include/exec/helper-proto.h
index 954bef85c..effdd4383 100644
--- a/include/exec/helper-proto.h
+++ b/include/exec/helper-proto.h
@@ -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);
diff --git a/include/exec/helper-tcg.h b/include/exec/helper-tcg.h
index bb9287727..79fa3c8c8 100644
--- a/include/exec/helper-tcg.h
+++ b/include/exec/helper-tcg.h
@@ -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, \
diff --git a/include/exec/hwaddr.h b/include/exec/hwaddr.h
index a71c93cc8..c9eb78fba 100644
--- a/include/exec/hwaddr.h
+++ b/include/exec/hwaddr.h
@@ -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'). */
diff --git a/include/exec/ioport.h b/include/exec/ioport.h
index a298b89ce..3bd672262 100644
--- a/include/exec/ioport.h
+++ b/include/exec/ioport.h
@@ -24,6 +24,13 @@
#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;
diff --git a/include/exec/memory.h b/include/exec/memory.h
index 3e4d4164c..e2a3e9953 100644
--- a/include/exec/memory.h
+++ b/include/exec/memory.h
@@ -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,
diff --git a/include/exec/poison.h b/include/exec/poison.h
index 3ca7929cc..a4b1eca24 100644
--- a/include/exec/poison.h
+++ b/include/exec/poison.h
@@ -37,6 +37,14 @@
#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
diff --git a/include/exec/ram_addr.h b/include/exec/ram_addr.h
index 2a9465da1..5adf7a4fc 100644
--- a/include/exec/ram_addr.h
+++ b/include/exec/ram_addr.h
@@ -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))
diff --git a/include/exec/softmmu-semi.h b/include/exec/softmmu-semi.h
index 7eefad8f3..3a58c3f08 100644
--- a/include/exec/softmmu-semi.h
+++ b/include/exec/softmmu-semi.h
@@ -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
index dce95d92d..000000000
--- a/include/exec/tb-context.h
+++ /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
index 2c40b5c46..000000000
--- a/include/exec/tb-hash-xx.h
+++ /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 */
diff --git a/include/exec/tb-hash.h b/include/exec/tb-hash.h
index 2c27490cb..0f4e8a08a 100644
--- a/include/exec/tb-hash.h
+++ b/include/exec/tb-hash.h
@@ -17,10 +17,8 @@
* 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
diff --git a/include/exec/user/abitypes.h b/include/exec/user/abitypes.h
index ba188608c..80eedaccf 100644
--- a/include/exec/user/abitypes.h
+++ b/include/exec/user/abitypes.h
@@ -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
@@ -15,10 +14,6 @@
#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
diff --git a/include/exec/user/thunk.h b/include/exec/user/thunk.h
index f19ef4b23..ad1d60266 100644
--- a/include/exec/user/thunk.h
+++ b/include/exec/user/thunk.h
@@ -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);
diff --git a/include/fpu/softfloat.h b/include/fpu/softfloat.h
index 1bde349b7..c93706253 100644
--- a/include/fpu/softfloat.h
+++ b/include/fpu/softfloat.h
@@ -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 */
diff --git a/include/glib-compat.h b/include/glib-compat.h
index 8d5a7f380..03d8b1267 100644
--- a/include/glib-compat.h
+++ b/include/glib-compat.h
@@ -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,
diff --git a/include/hw/acpi/acpi-defs.h b/include/hw/acpi/acpi-defs.h
index 41c1d95c4..c7a03d43b 100644
--- a/include/hw/acpi/acpi-defs.h
+++ b/include/hw/acpi/acpi-defs.h
@@ -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;
diff --git a/include/hw/acpi/acpi.h b/include/hw/acpi/acpi.h
index 7b3d93cf0..e0978c8b9 100644
--- a/include/hw/acpi/acpi.h
+++ b/include/hw/acpi/acpi.h
@@ -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
@@ -91,6 +89,13 @@
/* 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 */
diff --git a/include/hw/acpi/acpi_dev_interface.h b/include/hw/acpi/acpi_dev_interface.h
index da4ef7fbd..f245f8d23 100644
--- a/include/hw/acpi/acpi_dev_interface.h
+++ b/include/hw/acpi/acpi_dev_interface.h
@@ -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
diff --git a/include/hw/acpi/aml-build.h b/include/hw/acpi/aml-build.h
index e5f087803..2c994b351 100644
--- a/include/hw/acpi/aml-build.h
+++ b/include/hw/acpi/aml-build.h
@@ -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
diff --git a/include/hw/acpi/bios-linker-loader.h b/include/hw/acpi/bios-linker-loader.h
index fa1e5d1a4..82f1af643 100644
--- a/include/hw/acpi/bios-linker-loader.h
+++ b/include/hw/acpi/bios-linker-loader.h
@@ -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
index 89ce17294..000000000
--- a/include/hw/acpi/cpu.h
+++ /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
diff --git a/include/hw/acpi/cpu_hotplug.h b/include/hw/acpi/cpu_hotplug.h
index 3b932abbb..f22640e38 100644
--- a/include/hw/acpi/cpu_hotplug.h
+++ b/include/hw/acpi/cpu_hotplug.h
@@ -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
diff --git a/include/hw/acpi/ich9.h b/include/hw/acpi/ich9.h
index a352c94fd..63fa19814 100644
--- a/include/hw/acpi/ich9.h
+++ b/include/hw/acpi/ich9.h
@@ -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
index ab2bb2904..000000000
--- a/include/hw/acpi/ipmi.h
+++ /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 */
diff --git a/include/hw/acpi/memory_hotplug.h b/include/hw/acpi/memory_hotplug.h
index d2c745239..3a646b12e 100644
--- a/include/hw/acpi/memory_hotplug.h
+++ b/include/hw/acpi/memory_hotplug.h
@@ -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,
diff --git a/include/hw/acpi/pcihp.h b/include/hw/acpi/pcihp.h
index 04528b78d..79a43923e 100644
--- a/include/hw/acpi/pcihp.h
+++ b/include/hw/acpi/pcihp.h
@@ -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 */
diff --git a/include/hw/arm/arm.h b/include/hw/arm/arm.h
index aeeebfed9..b2517f9a4 100644
--- a/include/hw/arm/arm.h
+++ b/include/hw/arm/arm.h
@@ -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 */
diff --git a/include/hw/arm/ast2400.h b/include/hw/arm/ast2400.h
index 7833bc716..f16a1ed25 100644
--- a/include/hw/arm/ast2400.h
+++ b/include/hw/arm/ast2400.h
@@ -14,10 +14,7 @@
#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"
diff --git a/include/hw/arm/digic.h b/include/hw/arm/digic.h
index 63785baaa..a739d6ae6 100644
--- a/include/hw/arm/digic.h
+++ b/include/hw/arm/digic.h
@@ -19,6 +19,7 @@
#define HW_ARM_DIGIC_H
#include "cpu.h"
+
#include "hw/timer/digic-timer.h"
#include "hw/char/digic-uart.h"
diff --git a/include/hw/arm/exynos4210.h b/include/hw/arm/exynos4210.h
index 29fef8bfa..5c1820f88 100644
--- a/include/hw/arm/exynos4210.h
+++ b/include/hw/arm/exynos4210.h
@@ -22,12 +22,12 @@
*
*/
-#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
index ec6c509d7..000000000
--- a/include/hw/arm/fsl-imx6.h
+++ /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 */
diff --git a/include/hw/arm/omap.h b/include/hw/arm/omap.h
index f026c8df5..0ad5fb883 100644
--- a/include/hw/arm/omap.h
+++ b/include/hw/arm/omap.h
@@ -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
diff --git a/include/hw/arm/pxa.h b/include/hw/arm/pxa.h
index dd1a48b0c..259b85249 100644
--- a/include/hw/arm/pxa.h
+++ b/include/hw/arm/pxa.h
@@ -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 */
diff --git a/include/hw/arm/soc_dma.h b/include/hw/arm/soc_dma.h
index fae322997..7379731af 100644
--- a/include/hw/arm/soc_dma.h
+++ b/include/hw/arm/soc_dma.h
@@ -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"
diff --git a/include/hw/arm/stm32f205_soc.h b/include/hw/arm/stm32f205_soc.h
index 779b5da2d..0390eff80 100644
--- a/include/hw/arm/stm32f205_soc.h
+++ b/include/hw/arm/stm32f205_soc.h
@@ -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"
diff --git a/include/hw/arm/virt-acpi-build.h b/include/hw/arm/virt-acpi-build.h
index e43330ad6..7d3700ebf 100644
--- a/include/hw/arm/virt-acpi-build.h
+++ b/include/hw/arm/virt-acpi-build.h
@@ -22,7 +22,6 @@
#include "qemu-common.h"
#include "hw/arm/virt.h"
-#include "qemu/notify.h"
#define ACPI_GICC_ENABLED 1
diff --git a/include/hw/arm/virt.h b/include/hw/arm/virt.h
index 965019325..ecd858960 100644
--- a/include/hw/arm/virt.h
+++ b/include/hw/arm/virt.h
@@ -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
@@ -41,10 +40,6 @@
#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,
diff --git a/include/hw/arm/xlnx-zynqmp.h b/include/hw/arm/xlnx-zynqmp.h
index c2931bf39..2332596b4 100644
--- a/include/hw/arm/xlnx-zynqmp.h
+++ b/include/hw/arm/xlnx-zynqmp.h
@@ -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
diff --git a/include/hw/audio/audio.h b/include/hw/audio/audio.h
index 55d40f71b..b28abdd3f 100644
--- a/include/hw/audio/audio.h
+++ b/include/hw/audio/audio.h
@@ -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));
diff --git a/include/hw/audio/pcspk.h b/include/hw/audio/pcspk.h
index 172afbf14..ef95dd136 100644
--- a/include/hw/audio/pcspk.h
+++ b/include/hw/audio/pcspk.h
@@ -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 */
diff --git a/include/hw/block/block.h b/include/hw/block/block.h
index df9d207d8..984660efd 100644
--- a/include/hw/block/block.h
+++ b/include/hw/block/block.h
@@ -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 */
diff --git a/include/hw/block/flash.h b/include/hw/block/flash.h
index 67c3aa329..50ccbbcf1 100644
--- a/include/hw/block/flash.h
+++ b/include/hw/block/flash.h
@@ -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 */
diff --git a/include/hw/boards.h b/include/hw/boards.h
index 3e69eca03..8d4fe56b5 100644
--- a/include/hw/boards.h
+++ b/include/hw/boards.h
@@ -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
diff --git a/include/hw/bt.h b/include/hw/bt.h
index 185e79df2..c7c7909a3 100644
--- a/include/hw/bt.h
+++ b/include/hw/bt.h
@@ -24,7 +24,7 @@
*/
#ifndef HW_BT_H
-#define HW_BT_H
+#define HW_BT_H 1
#include "hw/irq.h"
diff --git a/include/hw/char/cadence_uart.h b/include/hw/char/cadence_uart.h
index a12773c07..6310f5251 100644
--- a/include/hw/char/cadence_uart.h
+++ b/include/hw/char/cadence_uart.h
@@ -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
diff --git a/include/hw/char/escc.h b/include/hw/char/escc.h
index 297e2ebcd..2742d70ea 100644
--- a/include/hw/char/escc.h
+++ b/include/hw/char/escc.h
@@ -1,5 +1,5 @@
#ifndef HW_ESCC_H
-#define HW_ESCC_H
+#define HW_ESCC_H 1
/* escc.c */
#define TYPE_ESCC "escc"
diff --git a/include/hw/char/lm32_juart.h b/include/hw/char/lm32_juart.h
index e7c6fb5a3..70dc416e9 100644
--- a/include/hw/char/lm32_juart.h
+++ b/include/hw/char/lm32_juart.h
@@ -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
index 0ca7c1941..000000000
--- a/include/hw/char/pl011.h
+++ /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
diff --git a/include/hw/char/serial.h b/include/hw/char/serial.h
index a4fd3d559..15beb6b45 100644
--- a/include/hw/char/serial.h
+++ b/include/hw/char/serial.h
@@ -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
index 8b4fc5495..000000000
--- a/include/hw/char/xilinx_uartlite.h
+++ /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
diff --git a/include/hw/compat.h b/include/hw/compat.h
index 7ee7299c3..81fc19b96 100644
--- a/include/hw/compat.h
+++ b/include/hw/compat.h
@@ -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
index 79ac79c29..000000000
--- a/include/hw/cpu/core.h
+++ /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
diff --git a/include/hw/cris/etraxfs.h b/include/hw/cris/etraxfs.h
index 723a2753c..73a6134c1 100644
--- a/include/hw/cris/etraxfs.h
+++ b/include/hw/cris/etraxfs.h
@@ -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
diff --git a/include/hw/cris/etraxfs_dma.h b/include/hw/cris/etraxfs_dma.h
index f6f33e098..38104a67b 100644
--- a/include/hw/cris/etraxfs_dma.h
+++ b/include/hw/cris/etraxfs_dma.h
@@ -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
index 6880ee36a..000000000
--- a/include/hw/display/dpcd.h
+++ /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
index ee046a5fa..000000000
--- a/include/hw/display/xlnx_dp.h
+++ /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
index 664df28ae..000000000
--- a/include/hw/dma/xlnx_dpdma.h
+++ /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 */
diff --git a/include/hw/empty_slot.h b/include/hw/empty_slot.h
index 123a9f898..6079602cd 100644
--- a/include/hw/empty_slot.h
+++ b/include/hw/empty_slot.h
@@ -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);
diff --git a/include/hw/fw-path-provider.h b/include/hw/fw-path-provider.h
index 050cb05d9..7afaec0b1 100644
--- a/include/hw/fw-path-provider.h
+++ b/include/hw/fw-path-provider.h
@@ -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"
diff --git a/include/hw/gpio/imx_gpio.h b/include/hw/gpio/imx_gpio.h
index ffab437f2..b15a09fbc 100644
--- a/include/hw/gpio/imx_gpio.h
+++ b/include/hw/gpio/imx_gpio.h
@@ -17,10 +17,10 @@
* 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_ */
diff --git a/include/hw/hotplug.h b/include/hw/hotplug.h
index c0db869f8..da1d0e4ab 100644
--- a/include/hw/hotplug.h
+++ b/include/hw/hotplug.h
@@ -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.
diff --git a/include/hw/hw.h b/include/hw/hw.h
index 3669ebd91..2cb69d5f5 100644
--- a/include/hw/hw.h
+++ b/include/hw/hw.h
@@ -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
index f9020acde..000000000
--- a/include/hw/i2c/aspeed_i2c.h
+++ /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
index d9b5f33f5..000000000
--- a/include/hw/i2c/i2c-ddc.h
+++ /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 */
diff --git a/include/hw/i2c/i2c.h b/include/hw/i2c/i2c.h
index c4085aa36..4986ebc73 100644
--- a/include/hw/i2c/i2c.h
+++ b/include/hw/i2c/i2c.h
@@ -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);
diff --git a/include/hw/i2c/imx_i2c.h b/include/hw/i2c/imx_i2c.h
index 7c73a1fa2..e2ee8eaee 100644
--- a/include/hw/i2c/imx_i2c.h
+++ b/include/hw/i2c/imx_i2c.h
@@ -18,10 +18,10 @@
*
*/
-#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_ */
diff --git a/include/hw/i2c/pm_smbus.h b/include/hw/i2c/pm_smbus.h
index 2a837afdc..926603fdf 100644
--- a/include/hw/i2c/pm_smbus.h
+++ b/include/hw/i2c/pm_smbus.h
@@ -17,4 +17,4 @@ typedef struct PMSMBus {
void pm_smbus_init(DeviceState *parent, PMSMBus *smb);
-#endif /* PM_SMBUS_H */
+#endif /* !PM_SMBUS_H */
diff --git a/include/hw/i386/apic-msidef.h b/include/hw/i386/apic-msidef.h
index 8b4d4cca5..6e2eb71f2 100644
--- a/include/hw/i386/apic-msidef.h
+++ b/include/hw/i386/apic-msidef.h
@@ -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 */
diff --git a/include/hw/i386/apic.h b/include/hw/i386/apic.h
index ea48ea938..51eb6d388 100644
--- a/include/hw/i386/apic.h
+++ b/include/hw/i386/apic.h
@@ -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
diff --git a/include/hw/i386/apic_internal.h b/include/hw/i386/apic_internal.h
index 06c4e9f6f..74fe935e8 100644
--- a/include/hw/i386/apic_internal.h
+++ b/include/hw/i386/apic_internal.h
@@ -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
@@ -121,6 +120,8 @@
#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 */
diff --git a/include/hw/i386/ich9.h b/include/hw/i386/ich9.h
index 5fd7e97d2..d04dcdcfb 100644
--- a/include/hw/i386/ich9.h
+++ b/include/hw/i386/ich9.h
@@ -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
diff --git a/include/hw/i386/intel_iommu.h b/include/hw/i386/intel_iommu.h
index a42dbd745..b024ffa72 100644
--- a/include/hw/i386/intel_iommu.h
+++ b/include/hw/i386/intel_iommu.h
@@ -23,10 +23,6 @@
#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)
@@ -47,22 +44,12 @@
#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,
diff --git a/include/hw/i386/ioapic.h b/include/hw/i386/ioapic.h
index 9c8816f11..6245388c5 100644
--- a/include/hw/i386/ioapic.h
+++ b/include/hw/i386/ioapic.h
@@ -25,4 +25,4 @@
void ioapic_eoi_broadcast(int vector);
-#endif /* HW_IOAPIC_H */
+#endif /* !HW_IOAPIC_H */
diff --git a/include/hw/i386/ioapic_internal.h b/include/hw/i386/ioapic_internal.h
index a11d86de4..797ed4730 100644
--- a/include/hw/i386/ioapic_internal.h
+++ b/include/hw/i386/ioapic_internal.h
@@ -25,12 +25,12 @@
#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
@@ -47,11 +47,6 @@
#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 */
diff --git a/include/hw/i386/pc.h b/include/hw/i386/pc.h
index 74c175c1e..96f0b66c7 100644
--- a/include/hw/i386/pc.h
+++ b/include/hw/i386/pc.h
@@ -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",\
diff --git a/include/hw/i386/topology.h b/include/hw/i386/topology.h
index 1ebaee0f7..fc9557239 100644
--- a/include/hw/i386/topology.h
+++ b/include/hw/i386/topology.h
@@ -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
index c48e8dd59..000000000
--- a/include/hw/i386/x86-iommu.h
+++ /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
diff --git a/include/hw/input/adb.h b/include/hw/input/adb.h
index 3ae8445e9..db51d0380 100644
--- a/include/hw/input/adb.h
+++ b/include/hw/input/adb.h
@@ -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__) */
diff --git a/include/hw/input/ps2.h b/include/hw/input/ps2.h
index b9ceee415..7c45ce7ce 100644
--- a/include/hw/input/ps2.h
+++ b/include/hw/input/ps2.h
@@ -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 */
diff --git a/include/hw/intc/allwinner-a10-pic.h b/include/hw/intc/allwinner-a10-pic.h
index 1d314a70d..5721b2e6b 100644
--- a/include/hw/intc/allwinner-a10-pic.h
+++ b/include/hw/intc/allwinner-a10-pic.h
@@ -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)
diff --git a/include/hw/intc/arm_gic.h b/include/hw/intc/arm_gic.h
index 42bb535fd..0971e3771 100644
--- a/include/hw/intc/arm_gic.h
+++ b/include/hw/intc/arm_gic.h
@@ -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
index 4a6fd85e2..000000000
--- a/include/hw/intc/arm_gicv3.h
+++ /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
diff --git a/include/hw/intc/arm_gicv3_common.h b/include/hw/intc/arm_gicv3_common.h
index 341a3118f..c2fd8da4e 100644
--- a/include/hw/intc/arm_gicv3_common.h
+++ b/include/hw/intc/arm_gicv3_common.h
@@ -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
@@ -27,166 +26,14 @@
#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
index b98d50094..000000000
--- a/include/hw/intc/mips_gic.h
+++ /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 */
diff --git a/include/hw/ipack/ipack.h b/include/hw/ipack/ipack.h
index e33e032ce..e95ffe820 100644
--- a/include/hw/ipack/ipack.h
+++ b/include/hw/ipack/ipack.h
@@ -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.
diff --git a/include/hw/ipmi/ipmi.h b/include/hw/ipmi/ipmi.h
index 91b83b5bb..74a2b5af9 100644
--- a/include/hw/ipmi/ipmi.h
+++ b/include/hw/ipmi/ipmi.h
@@ -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__)
diff --git a/include/hw/isa/i8257.h b/include/hw/isa/i8257.h
index aa211c0df..8c44d3628 100644
--- a/include/hw/isa/i8257.h
+++ b/include/hw/isa/i8257.h
@@ -39,3 +39,4 @@ typedef struct I8257State {
} I8257State;
#endif
+
diff --git a/include/hw/isa/i8259_internal.h b/include/hw/isa/i8259_internal.h
index 6954b6ec5..cded50963 100644
--- a/include/hw/isa/i8259_internal.h
+++ b/include/hw/isa/i8259_internal.h
@@ -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 */
diff --git a/include/hw/isa/isa.h b/include/hw/isa/isa.h
index 7693ac545..ffb2ea7cd 100644
--- a/include/hw/isa/isa.h
+++ b/include/hw/isa/isa.h
@@ -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);
diff --git a/include/hw/m68k/mcf.h b/include/hw/m68k/mcf.h
index 0f0d2288e..fbc8dc26d 100644
--- a/include/hw/m68k/mcf.h
+++ b/include/hw/m68k/mcf.h
@@ -2,8 +2,6 @@
#define HW_MCF_H
/* Motorola ColdFire device prototypes. */
-#include "target-m68k/cpu-qom.h"
-
struct MemoryRegion;
/* mcf_uart.c */
diff --git a/include/hw/mem/nvdimm.h b/include/hw/mem/nvdimm.h
index 1cfe9e01c..517de9c36 100644
--- a/include/hw/mem/nvdimm.h
+++ b/include/hw/mem/nvdimm.h
@@ -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, ...) \
@@ -34,60 +33,7 @@
} \
} 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
diff --git a/include/hw/mem/pc-dimm.h b/include/hw/mem/pc-dimm.h
index 1e483f267..218dfb0ed 100644
--- a/include/hw/mem/pc-dimm.h
+++ b/include/hw/mem/pc-dimm.h
@@ -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
*/
diff --git a/include/hw/mips/cps.h b/include/hw/mips/cps.h
index 526b8d0b1..4dbae9c8c 100644
--- a/include/hw/mips/cps.h
+++ b/include/hw/mips/cps.h
@@ -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;
diff --git a/include/hw/mips/cpudevs.h b/include/hw/mips/cpudevs.h
index 8673daa39..b2626f292 100644
--- a/include/hw/mips/cpudevs.h
+++ b/include/hw/mips/cpudevs.h
@@ -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
diff --git a/include/hw/misc/arm_integrator_debug.h b/include/hw/misc/arm_integrator_debug.h
index 0077dacb4..37789b69d 100644
--- a/include/hw/misc/arm_integrator_debug.h
+++ b/include/hw/misc/arm_integrator_debug.h
@@ -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
index fdfd98228..000000000
--- a/include/hw/misc/aspeed_scu.h
+++ /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
index 68ade8a90..000000000
--- a/include/hw/misc/auxbus.h
+++ /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
index eb3640732..000000000
--- a/include/hw/misc/imx6_src.h
+++ /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 */
diff --git a/include/hw/misc/imx_ccm.h b/include/hw/misc/imx_ccm.h
index 33cbc0995..48a7afad5 100644
--- a/include/hw/misc/imx_ccm.h
+++ b/include/hw/misc/imx_ccm.h
@@ -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 {
diff --git a/include/hw/misc/mips_cmgcr.h b/include/hw/misc/mips_cmgcr.h
index a209d91de..cc60eefa5 100644
--- a/include/hw/misc/mips_cmgcr.h
+++ b/include/hw/misc/mips_cmgcr.h
@@ -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)
@@ -26,45 +26,23 @@
#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 */
diff --git a/include/hw/misc/tmp105_regs.h b/include/hw/misc/tmp105_regs.h
index ef015ee5c..9b55abaf9 100644
--- a/include/hw/misc/tmp105_regs.h
+++ b/include/hw/misc/tmp105_regs.h
@@ -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:
diff --git a/include/hw/net/allwinner_emac.h b/include/hw/net/allwinner_emac.h
index 4cc8aab7e..9f21aa7e4 100644
--- a/include/hw/net/allwinner_emac.h
+++ b/include/hw/net/allwinner_emac.h
@@ -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"
diff --git a/include/hw/net/imx_fec.h b/include/hw/net/imx_fec.h
index 62ad473b0..cbf86509e 100644
--- a/include/hw/net/imx_fec.h
+++ b/include/hw/net/imx_fec.h
@@ -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>
*
@@ -27,147 +27,27 @@
#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
diff --git a/include/hw/nmi.h b/include/hw/nmi.h
index d092c684a..f4cec6257 100644
--- a/include/hw/nmi.h
+++ b/include/hw/nmi.h
@@ -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 */
diff --git a/include/hw/nvram/fw_cfg.h b/include/hw/nvram/fw_cfg.h
index 5c27a1f0d..d00811258 100644
--- a/include/hw/nvram/fw_cfg.h
+++ b/include/hw/nvram/fw_cfg.h
@@ -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
diff --git a/include/hw/nvram/openbios_firmware_abi.h b/include/hw/nvram/openbios_firmware_abi.h
index 74cfd5618..c66ee2268 100644
--- a/include/hw/nvram/openbios_firmware_abi.h
+++ b/include/hw/nvram/openbios_firmware_abi.h
@@ -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 */
diff --git a/include/hw/pci-host/apb.h b/include/hw/pci-host/apb.h
index b19bd55c4..736db6118 100644
--- a/include/hw/pci-host/apb.h
+++ b/include/hw/pci-host/apb.h
@@ -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"
diff --git a/include/hw/pci-host/ppce500.h b/include/hw/pci-host/ppce500.h
index e3a374230..61f773ef3 100644
--- a/include/hw/pci-host/ppce500.h
+++ b/include/hw/pci-host/ppce500.h
@@ -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)
{
diff --git a/include/hw/pci-host/q35.h b/include/hw/pci-host/q35.h
index 94486fdd3..c5c073dde 100644
--- a/include/hw/pci-host/q35.h
+++ b/include/hw/pci-host/q35.h
@@ -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 */
diff --git a/include/hw/pci-host/spapr.h b/include/hw/pci-host/spapr.h
index 5adc603d4..03ee00640 100644
--- a/include/hw/pci-host/spapr.h
+++ b/include/hw/pci-host/spapr.h
@@ -16,11 +16,13 @@
* 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__ */
diff --git a/include/hw/pci/msi.h b/include/hw/pci/msi.h
index 4837bcf49..8124908ab 100644
--- a/include/hw/pci/msi.h
+++ b/include/hw/pci/msi.h
@@ -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);
diff --git a/include/hw/pci/msix.h b/include/hw/pci/msix.h
index 048a29dd2..72e5f931c 100644
--- a/include/hw/pci/msix.h
+++ b/include/hw/pci/msix.h
@@ -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);
diff --git a/include/hw/pci/pci.h b/include/hw/pci/pci.h
index 929ec2fb0..e7f2df5b7 100644
--- a/include/hw/pci/pci.h
+++ b/include/hw/pci/pci.h
@@ -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
diff --git a/include/hw/pci/pci_bridge.h b/include/hw/pci/pci_bridge.h
index 847fd7db3..ed4aff6cd 100644
--- a/include/hw/pci/pci_bridge.h
+++ b/include/hw/pci/pci_bridge.h
@@ -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 */
diff --git a/include/hw/pci/pci_bus.h b/include/hw/pci/pci_bus.h
index 5484a9b5c..403fec6e5 100644
--- a/include/hw/pci/pci_bus.h
+++ b/include/hw/pci/pci_bus.h
@@ -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;
diff --git a/include/hw/pci/pci_ids.h b/include/hw/pci/pci_ids.h
index d77ca60a0..db85afa03 100644
--- a/include/hw/pci/pci_ids.h
+++ b/include/hw/pci/pci_ids.h
@@ -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 */
diff --git a/include/hw/pci/pci_regs.h b/include/hw/pci/pci_regs.h
index 7a8314257..ba8cbe927 100644
--- a/include/hw/pci/pci_regs.h
+++ b/include/hw/pci/pci_regs.h
@@ -1,3 +1 @@
#include "standard-headers/linux/pci_regs.h"
-
-#define PCI_PM_CAP_VER_1_1 0x0002 /* PCI PM spec ver. 1.1 */
diff --git a/include/hw/pci/pcie.h b/include/hw/pci/pcie.h
index 056d25e53..b48a7a2c5 100644
--- a/include/hw/pci/pcie.h
+++ b/include/hw/pci/pcie.h
@@ -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;
diff --git a/include/hw/pci/pcie_regs.h b/include/hw/pci/pcie_regs.h
index a95522a13..6a28b33e6 100644
--- a/include/hw/pci/pcie_regs.h
+++ b/include/hw/pci/pcie_regs.h
@@ -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
@@ -27,11 +26,11 @@
(((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
diff --git a/include/hw/pcmcia.h b/include/hw/pcmcia.h
index 79cac9c76..98406ffbc 100644
--- a/include/hw/pcmcia.h
+++ b/include/hw/pcmcia.h
@@ -1,5 +1,5 @@
#ifndef HW_PCMCIA_H
-#define HW_PCMCIA_H
+#define HW_PCMCIA_H 1
/* PCMCIA/Cardbus */
diff --git a/include/hw/platform-bus.h b/include/hw/platform-bus.h
index a00775cba..bd42b8380 100644
--- a/include/hw/platform-bus.h
+++ b/include/hw/platform-bus.h
@@ -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 */
diff --git a/include/hw/ppc/mac_dbdma.h b/include/hw/ppc/mac_dbdma.h
index a8603877d..0cce4e8bb 100644
--- a/include/hw/ppc/mac_dbdma.h
+++ b/include/hw/ppc/mac_dbdma.h
@@ -19,13 +19,11 @@
* 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;
};
/*
diff --git a/include/hw/ppc/openpic.h b/include/hw/ppc/openpic.h
index 6137e2d7a..ee67098cb 100644
--- a/include/hw/ppc/openpic.h
+++ b/include/hw/ppc/openpic.h
@@ -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__ */
diff --git a/include/hw/ppc/ppc.h b/include/hw/ppc/ppc.h
index 00c1fb1e7..14efd0ca3 100644
--- a/include/hw/ppc/ppc.h
+++ b/include/hw/ppc/ppc.h
@@ -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
diff --git a/include/hw/ppc/ppc4xx.h b/include/hw/ppc/ppc4xx.h
index 3b01ae831..91d84bad6 100644
--- a/include/hw/ppc/ppc4xx.h
+++ b/include/hw/ppc/ppc4xx.h
@@ -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) */
diff --git a/include/hw/ppc/spapr.h b/include/hw/ppc/spapr.h
index caf7be919..815d5eec4 100644
--- a/include/hw/ppc/spapr.h
+++ b/include/hw/ppc/spapr.h
@@ -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
index 1c9b3195c..000000000
--- a/include/hw/ppc/spapr_cpu_core.h
+++ /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
diff --git a/include/hw/ppc/spapr_drc.h b/include/hw/ppc/spapr_drc.h
index fa531d5c2..fa21ba044 100644
--- a/include/hw/ppc/spapr_drc.h
+++ b/include/hw/ppc/spapr_drc.h
@@ -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__ */
diff --git a/include/hw/ppc/spapr_vio.h b/include/hw/ppc/spapr_vio.h
index d4a1e2c8a..c9733e755 100644
--- a/include/hw/ppc/spapr_vio.h
+++ b/include/hw/ppc/spapr_vio.h
@@ -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 */
diff --git a/include/hw/ppc/xics.h b/include/hw/ppc/xics.h
index 2db9f938d..f60b06ae8 100644
--- a/include/hw/ppc/xics.h
+++ b/include/hw/ppc/xics.h
@@ -24,34 +24,28 @@
* 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__ */
diff --git a/include/hw/ptimer.h b/include/hw/ptimer.h
index e397db5bd..8ebacbbda 100644
--- a/include/hw/ptimer.h
+++ b/include/hw/ptimer.h
@@ -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);
diff --git a/include/hw/qdev-core.h b/include/hw/qdev-core.h
index 4b4b33bec..1ce02b20d 100644
--- a/include/hw/qdev-core.h
+++ b/include/hw/qdev-core.h
@@ -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. ***/
diff --git a/include/hw/qdev-properties.h b/include/hw/qdev-properties.h
index 2a9d2f90e..0586cacce 100644
--- a/include/hw/qdev-properties.h
+++ b/include/hw/qdev-properties.h
@@ -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
index 8c12233b7..000000000
--- a/include/hw/register.h
+++ /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
index 5a0203be5..000000000
--- a/include/hw/s390x/css-bridge.h
+++ /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
diff --git a/include/hw/s390x/ebcdic.h b/include/hw/s390x/ebcdic.h
index 69a04cab6..1d6fde9c1 100644
--- a/include/hw/s390x/ebcdic.h
+++ b/include/hw/s390x/ebcdic.h
@@ -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_ */
diff --git a/include/hw/s390x/event-facility.h b/include/hw/s390x/event-facility.h
index def1bb0c0..dd8881838 100644
--- a/include/hw/s390x/event-facility.h
+++ b/include/hw/s390x/event-facility.h
@@ -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"
diff --git a/include/hw/s390x/s390-virtio-ccw.h b/include/hw/s390x/s390-virtio-ccw.h
index a0c1fc808..ab08332fe 100644
--- a/include/hw/s390x/s390-virtio-ccw.h
+++ b/include/hw/s390x/s390-virtio-ccw.h
@@ -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
diff --git a/include/hw/s390x/s390_flic.h b/include/hw/s390x/s390_flic.h
index 9094edadf..200e7e93f 100644
--- a/include/hw/s390x/s390_flic.h
+++ b/include/hw/s390x/s390_flic.h
@@ -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 */
diff --git a/include/hw/s390x/sclp.h b/include/hw/s390x/sclp.h
index ba28d1dd0..b0c71b555 100644
--- a/include/hw/s390x/sclp.h
+++ b/include/hw/s390x/sclp.h
@@ -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
diff --git a/include/hw/s390x/storage-keys.h b/include/hw/s390x/storage-keys.h
index 62df48ec0..72b850cb1 100644
--- a/include/hw/s390x/storage-keys.h
+++ b/include/hw/s390x/storage-keys.h
@@ -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 */
diff --git a/include/hw/scsi/scsi.h b/include/hw/scsi/scsi.h
index 94d786810..8acd3fa99 100644
--- a/include/hw/scsi/scsi.h
+++ b/include/hw/scsi/scsi.h
@@ -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;
diff --git a/include/hw/sd/sd.h b/include/hw/sd/sd.h
index 79909b247..d5d273a44 100644
--- a/include/hw/sd/sd.h
+++ b/include/hw/sd/sd.h
@@ -26,11 +26,8 @@
* (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 */
diff --git a/include/hw/sh4/sh.h b/include/hw/sh4/sh.h
index 070312d92..e61de9acc 100644
--- a/include/hw/sh4/sh.h
+++ b/include/hw/sh4/sh.h
@@ -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)
diff --git a/include/hw/sh4/sh_intc.h b/include/hw/sh4/sh_intc.h
index 7913bc48a..b7ddcb096 100644
--- a/include/hw/sh4/sh_intc.h
+++ b/include/hw/sh4/sh_intc.h
@@ -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
index 1c9aae38f..000000000
--- a/include/hw/smbios/ipmi.h
+++ /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 */
diff --git a/include/hw/smbios/smbios.h b/include/hw/smbios/smbios.h
index 1cd53cc58..76ccf7098 100644
--- a/include/hw/smbios/smbios.h
+++ b/include/hw/smbios/smbios.h
@@ -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 */
diff --git a/include/hw/sparc/grlib.h b/include/hw/sparc/grlib.h
index afbb9bc07..9a0db7b47 100644
--- a/include/hw/sparc/grlib.h
+++ b/include/hw/sparc/grlib.h
@@ -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
index def3b4507..000000000
--- a/include/hw/ssi/aspeed_smc.h
+++ /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
index 710395358..000000000
--- a/include/hw/ssi/imx_spi.h
+++ /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 */
diff --git a/include/hw/ssi/ssi.h b/include/hw/ssi/ssi.h
index 6a0c3c3cd..4a0a53903 100644
--- a/include/hw/ssi/ssi.h
+++ b/include/hw/ssi/ssi.h
@@ -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).
diff --git a/include/hw/ssi/xilinx_spips.h b/include/hw/ssi/xilinx_spips.h
index 06aa09629..dbb9eefba 100644
--- a/include/hw/ssi/xilinx_spips.h
+++ b/include/hw/ssi/xilinx_spips.h
@@ -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 */
diff --git a/include/hw/stream.h b/include/hw/stream.h
index c370ba0c6..30ccc5620 100644
--- a/include/hw/stream.h
+++ b/include/hw/stream.h
@@ -1,5 +1,5 @@
#ifndef STREAM_H
-#define STREAM_H
+#define STREAM_H 1
#include "qemu-common.h"
#include "qom/object.h"
diff --git a/include/hw/sysbus.h b/include/hw/sysbus.h
index e73a5b21a..cc1dba49b 100644
--- a/include/hw/sysbus.h
+++ b/include/hw/sysbus.h
@@ -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 */
diff --git a/include/hw/timer/a9gtimer.h b/include/hw/timer/a9gtimer.h
index 81c438878..98d8e0ae5 100644
--- a/include/hw/timer/a9gtimer.h
+++ b/include/hw/timer/a9gtimer.h
@@ -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 */
diff --git a/include/hw/timer/allwinner-a10-pit.h b/include/hw/timer/allwinner-a10-pit.h
index c0cc3e216..770bdc03c 100644
--- a/include/hw/timer/allwinner-a10-pit.h
+++ b/include/hw/timer/allwinner-a10-pit.h
@@ -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"
diff --git a/include/hw/timer/aspeed_timer.h b/include/hw/timer/aspeed_timer.h
index bd6c1a7f9..44dc2f89d 100644
--- a/include/hw/timer/aspeed_timer.h
+++ b/include/hw/timer/aspeed_timer.h
@@ -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 {
diff --git a/include/hw/timer/hpet.h b/include/hw/timer/hpet.h
index f04c4d323..f38bcfecd 100644
--- a/include/hw/timer/hpet.h
+++ b/include/hw/timer/hpet.h
@@ -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"
diff --git a/include/hw/timer/i8254.h b/include/hw/timer/i8254.h
index 5adae9fa4..434903348 100644
--- a/include/hw/timer/i8254.h
+++ b/include/hw/timer/i8254.h
@@ -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 */
diff --git a/include/hw/timer/i8254_internal.h b/include/hw/timer/i8254_internal.h
index dc09cc046..61a1bfbc4 100644
--- a/include/hw/timer/i8254_internal.h
+++ b/include/hw/timer/i8254_internal.h
@@ -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 */
diff --git a/include/hw/timer/imx_gpt.h b/include/hw/timer/imx_gpt.h
index eac59b2a7..461adbe53 100644
--- a/include/hw/timer/imx_gpt.h
+++ b/include/hw/timer/imx_gpt.h
@@ -74,12 +74,7 @@
#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 */
diff --git a/include/hw/timer/m48t59.h b/include/hw/timer/m48t59.h
index db5e43a8d..336792363 100644
--- a/include/hw/timer/m48t59.h
+++ b/include/hw/timer/m48t59.h
@@ -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 */
diff --git a/include/hw/timer/mc146818rtc.h b/include/hw/timer/mc146818rtc.h
index 7c8e64b20..eaf649767 100644
--- a/include/hw/timer/mc146818rtc.h
+++ b/include/hw/timer/mc146818rtc.h
@@ -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 */
diff --git a/include/hw/timer/mc146818rtc_regs.h b/include/hw/timer/mc146818rtc_regs.h
index 6ede6c832..ccdee42b3 100644
--- a/include/hw/timer/mc146818rtc_regs.h
+++ b/include/hw/timer/mc146818rtc_regs.h
@@ -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
index c8bc5d254..000000000
--- a/include/hw/timer/mips_gictimer.h
+++ /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 */
diff --git a/include/hw/tricore/tricore.h b/include/hw/tricore/tricore.h
index 89ef922c6..5f1325278 100644
--- a/include/hw/tricore/tricore.h
+++ b/include/hw/tricore/tricore.h
@@ -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"
diff --git a/include/hw/unicore32/puv3.h b/include/hw/unicore32/puv3.h
index 5a4839f8d..f37adcb66 100644
--- a/include/hw/unicore32/puv3.h
+++ b/include/hw/unicore32/puv3.h
@@ -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 */
diff --git a/include/hw/usb.h b/include/hw/usb.h
index 847c9dec7..163fe0490 100644
--- a/include/hw/usb.h
+++ b/include/hw/usb.h
@@ -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 {
diff --git a/include/hw/usb/ehci-regs.h b/include/hw/usb/ehci-regs.h
index 3e91b8e61..616f1b88c 100644
--- a/include/hw/usb/ehci-regs.h
+++ b/include/hw/usb/ehci-regs.h
@@ -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 */
diff --git a/include/hw/usb/uhci-regs.h b/include/hw/usb/uhci-regs.h
index fd45d29db..c7315c5e1 100644
--- a/include/hw/usb/uhci-regs.h
+++ b/include/hw/usb/uhci-regs.h
@@ -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)
diff --git a/include/hw/vfio/vfio-common.h b/include/hw/vfio/vfio-common.h
index 94dfae387..eb0e1b034 100644
--- a/include/hw/vfio/vfio-common.h
+++ b/include/hw/vfio/vfio-common.h
@@ -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 */
diff --git a/include/hw/vfio/vfio-platform.h b/include/hw/vfio/vfio-platform.h
index 9baaa2db0..b468f80b1 100644
--- a/include/hw/vfio/vfio-platform.h
+++ b/include/hw/vfio/vfio-platform.h
@@ -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*/
diff --git a/include/hw/vfio/vfio.h b/include/hw/vfio/vfio.h
index 86248f543..f27d59922 100644
--- a/include/hw/vfio/vfio.h
+++ b/include/hw/vfio/vfio.h
@@ -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);
diff --git a/include/hw/virtio/vhost-backend.h b/include/hw/virtio/vhost-backend.h
index cf7f0b5a6..95fcc9667 100644
--- a/include/hw/virtio/vhost-backend.h
+++ b/include/hw/virtio/vhost-backend.h
@@ -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_ */
diff --git a/include/hw/virtio/vhost.h b/include/hw/virtio/vhost.h
index e433089ea..b60d7585b 100644
--- a/include/hw/virtio/vhost.h
+++ b/include/hw/virtio/vhost.h
@@ -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
diff --git a/include/hw/virtio/virtio-access.h b/include/hw/virtio/virtio-access.h
index 440b4555e..8dc84f520 100644
--- a/include/hw/virtio/virtio-access.h
+++ b/include/hw/virtio/virtio-access.h
@@ -12,20 +12,14 @@
* (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 */
diff --git a/include/hw/virtio/virtio-balloon.h b/include/hw/virtio/virtio-balloon.h
index 1ea13bd6a..35f62ac11 100644
--- a/include/hw/virtio/virtio-balloon.h
+++ b/include/hw/virtio/virtio-balloon.h
@@ -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"
diff --git a/include/hw/virtio/virtio-blk.h b/include/hw/virtio/virtio-blk.h
index 180bd8db5..8f2b05651 100644
--- a/include/hw/virtio/virtio-blk.h
+++ b/include/hw/virtio/virtio-blk.h
@@ -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);
diff --git a/include/hw/virtio/virtio-bus.h b/include/hw/virtio/virtio-bus.h
index f3e5ef3f5..3f2c1363d 100644
--- a/include/hw/virtio/virtio-bus.h
+++ b/include/hw/virtio/virtio-bus.h
@@ -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 */
diff --git a/include/hw/virtio/virtio-gpu.h b/include/hw/virtio/virtio-gpu.h
index 20d1cd683..13b0ab084 100644
--- a/include/hw/virtio/virtio-gpu.h
+++ b/include/hw/virtio/virtio-gpu.h
@@ -11,15 +11,14 @@
* 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"
@@ -28,12 +27,13 @@
#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);
diff --git a/include/hw/virtio/virtio-input.h b/include/hw/virtio/virtio-input.h
index 55db31087..bddbd4b28 100644
--- a/include/hw/virtio/virtio-input.h
+++ b/include/hw/virtio/virtio-input.h
@@ -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 */
diff --git a/include/hw/virtio/virtio-net.h b/include/hw/virtio/virtio-net.h
index 91ed97cfc..0cabdb682 100644
--- a/include/hw/virtio/virtio-net.h
+++ b/include/hw/virtio/virtio-net.h
@@ -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"
diff --git a/include/hw/virtio/virtio-rng.h b/include/hw/virtio/virtio-rng.h
index 2d40abdbd..3f07de70c 100644
--- a/include/hw/virtio/virtio-rng.h
+++ b/include/hw/virtio/virtio-rng.h
@@ -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 {
diff --git a/include/hw/virtio/virtio-scsi.h b/include/hw/virtio/virtio-scsi.h
index a1e0cfb44..ba2f5ce07 100644
--- a/include/hw/virtio/virtio-scsi.h
+++ b/include/hw/virtio/virtio-scsi.h
@@ -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 */
diff --git a/include/hw/virtio/virtio-serial.h b/include/hw/virtio/virtio-serial.h
index 730c88d2a..12a55a19e 100644
--- a/include/hw/virtio/virtio-serial.h
+++ b/include/hw/virtio/virtio-serial.h
@@ -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"
diff --git a/include/hw/virtio/virtio.h b/include/hw/virtio/virtio.h
index d2490c197..6a37065c2 100644
--- a/include/hw/virtio/virtio.h
+++ b/include/hw/virtio/virtio.h
@@ -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);
diff --git a/include/hw/watchdog/wdt_diag288.h b/include/hw/watchdog/wdt_diag288.h
index 706d96b75..7f3fd450d 100644
--- a/include/hw/watchdog/wdt_diag288.h
+++ b/include/hw/watchdog/wdt_diag288.h
@@ -33,4 +33,4 @@ typedef struct DIAG288Class {
uint64_t func, uint64_t timeout);
} DIAG288Class;
-#endif /* WDT_DIAG288_H */
+#endif /* WDT_DIAG288_H */
diff --git a/include/hw/xen/xen.h b/include/hw/xen/xen.h
index a8f3afb03..6eb815aac 100644
--- a/include/hw/xen/xen.h
+++ b/include/hw/xen/xen.h
@@ -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);
diff --git a/include/hw/xen/xen_backend.h b/include/hw/xen/xen_backend.h
index 0df282ab5..c839eeb48 100644
--- a/include/hw/xen/xen_backend.h
+++ b/include/hw/xen/xen_backend.h
@@ -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);
diff --git a/include/hw/xen/xen_common.h b/include/hw/xen/xen_common.h
index bd39287b8..7b52e8ffc 100644
--- a/include/hw/xen/xen_common.h
+++ b/include/hw/xen/xen_common.h
@@ -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);
}
diff --git a/include/io/channel-buffer.h b/include/io/channel-buffer.h
index 3f4b3f29e..65c498b2c 100644
--- a/include/io/channel-buffer.h
+++ b/include/io/channel-buffer.h
@@ -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__ */
diff --git a/include/io/channel-command.h b/include/io/channel-command.h
index 336d47fa5..cfc177e78 100644
--- a/include/io/channel-command.h
+++ b/include/io/channel-command.h
@@ -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__ */
diff --git a/include/io/channel-file.h b/include/io/channel-file.h
index d2462c2ed..308e6d44d 100644
--- a/include/io/channel-file.h
+++ b/include/io/channel-file.h
@@ -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__ */
diff --git a/include/io/channel-socket.h b/include/io/channel-socket.h
index 711f8bf7c..70d06b40d 100644
--- a/include/io/channel-socket.h
+++ b/include/io/channel-socket.h
@@ -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__ */
diff --git a/include/io/channel-tls.h b/include/io/channel-tls.h
index d157eb10e..322eccbaa 100644
--- a/include/io/channel-tls.h
+++ b/include/io/channel-tls.h
@@ -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__ */
diff --git a/include/io/channel-util.h b/include/io/channel-util.h
index c0b79cf60..c93af8288 100644
--- a/include/io/channel-util.h
+++ b/include/io/channel-util.h
@@ -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__ */
diff --git a/include/io/channel-watch.h b/include/io/channel-watch.h
index 63bc4ae2d..76d764223 100644
--- a/include/io/channel-watch.h
+++ b/include/io/channel-watch.h
@@ -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__ */
diff --git a/include/io/channel-websock.h b/include/io/channel-websock.h
index 3c9ff8472..0dc21cc56 100644
--- a/include/io/channel-websock.h
+++ b/include/io/channel-websock.h
@@ -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__ */
diff --git a/include/io/channel.h b/include/io/channel.h
index 752e89f4d..d37acd29e 100644
--- a/include/io/channel.h
+++ b/include/io/channel.h
@@ -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__ */
diff --git a/include/io/task.h b/include/io/task.h
index 42028cb42..a993212ad 100644
--- a/include/io/task.h
+++ b/include/io/task.h
@@ -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__ */
diff --git a/include/libdecnumber/decContext.h b/include/libdecnumber/decContext.h
index cea6e4279..01365e231 100644
--- a/include/libdecnumber/decContext.h
+++ b/include/libdecnumber/decContext.h
@@ -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 */
diff --git a/include/libdecnumber/decNumber.h b/include/libdecnumber/decNumber.h
index aa115fed0..9fa4e6a0c 100644
--- a/include/libdecnumber/decNumber.h
+++ b/include/libdecnumber/decNumber.h
@@ -32,14 +32,15 @@
/* 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 */
diff --git a/include/libdecnumber/decNumberLocal.h b/include/libdecnumber/decNumberLocal.h
index 12cf1d8b6..94fb51292 100644
--- a/include/libdecnumber/decNumberLocal.h
+++ b/include/libdecnumber/decNumberLocal.h
@@ -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 */
@@ -659,4 +658,6 @@
/* [end of format-dependent macros and constants] */
#endif
+#else
+ #error decNumberLocal included more than once
#endif
diff --git a/include/libdecnumber/dpd/decimal128.h b/include/libdecnumber/dpd/decimal128.h
index aff261e55..7d9ee24f8 100644
--- a/include/libdecnumber/dpd/decimal128.h
+++ b/include/libdecnumber/dpd/decimal128.h
@@ -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 {
diff --git a/include/libdecnumber/dpd/decimal32.h b/include/libdecnumber/dpd/decimal32.h
index 6cb9e4362..de313e002 100644
--- a/include/libdecnumber/dpd/decimal32.h
+++ b/include/libdecnumber/dpd/decimal32.h
@@ -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 {
diff --git a/include/libdecnumber/dpd/decimal64.h b/include/libdecnumber/dpd/decimal64.h
index f29e57064..2f6c04940 100644
--- a/include/libdecnumber/dpd/decimal64.h
+++ b/include/libdecnumber/dpd/decimal64.h
@@ -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 {
diff --git a/include/migration/block.h b/include/migration/block.h
index 41a1ac8f7..ffa8ac0bd 100644
--- a/include/migration/block.h
+++ b/include/migration/block.h
@@ -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
index f3abbab65..000000000
--- a/include/migration/cpu.h
+++ /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
diff --git a/include/migration/migration.h b/include/migration/migration.h
index 3c96623d3..9e36a97fc 100644
--- a/include/migration/migration.h
+++ b/include/migration/migration.h
@@ -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);
diff --git a/include/migration/qemu-file.h b/include/migration/qemu-file.h
index abedd466c..3f6b4ed58 100644
--- a/include/migration/qemu-file.h
+++ b/include/migration/qemu-file.h
@@ -21,15 +21,18 @@
* 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)
{
diff --git a/include/migration/vmstate.h b/include/migration/vmstate.h
index 1638ee57f..84ee355ce 100644
--- a/include/migration/vmstate.h
+++ b/include/migration/vmstate.h
@@ -23,14 +23,13 @@
* 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)
diff --git a/include/monitor/hmp-target.h b/include/monitor/hmp-target.h
index 454e8ed15..bc2c9c04d 100644
--- a/include/monitor/hmp-target.h
+++ b/include/monitor/hmp-target.h
@@ -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 */
diff --git a/include/monitor/monitor.h b/include/monitor/monitor.h
index a714d8ef8..aa0f37320 100644
--- a/include/monitor/monitor.h
+++ b/include/monitor/monitor.h
@@ -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 */
diff --git a/include/monitor/qdev.h b/include/monitor/qdev.h
index 8e504bc66..c4b8a0514 100644
--- a/include/monitor/qdev.h
+++ b/include/monitor/qdev.h
@@ -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"
diff --git a/include/net/checksum.h b/include/net/checksum.h
index 7df472c2f..7de1acb79 100644
--- a/include/net/checksum.h
+++ b/include/net/checksum.h
@@ -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 */
diff --git a/include/net/eth.h b/include/net/eth.h
index 201317585..18d0be3b1 100644
--- a/include/net/eth.h
+++ b/include/net/eth.h
@@ -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
diff --git a/include/net/net.h b/include/net/net.h
index e8d9e9e4e..73e4c466e 100644
--- a/include/net/net.h
+++ b/include/net/net.h
@@ -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);
diff --git a/include/net/vhost-user.h b/include/net/vhost-user.h
index 5bcd8a628..85109f63a 100644
--- a/include/net/vhost-user.h
+++ b/include/net/vhost-user.h
@@ -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_ */
diff --git a/include/net/vhost_net.h b/include/net/vhost_net.h
index 5a08efffe..3389b410d 100644
--- a/include/net/vhost_net.h
+++ b/include/net/vhost_net.h
@@ -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
index b16177e1e..000000000
--- a/include/qapi/clone-visitor.h
+++ /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
diff --git a/include/qapi/dealloc-visitor.h b/include/qapi/dealloc-visitor.h
index b3e5c85fd..cf4c36d2d 100644
--- a/include/qapi/dealloc-visitor.h
+++ b/include/qapi/dealloc-visitor.h
@@ -18,11 +18,9 @@
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
diff --git a/include/qapi/error.h b/include/qapi/error.h
index 057665960..11be2327c 100644
--- a/include/qapi/error.h
+++ b/include/qapi/error.h
@@ -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.
diff --git a/include/qapi/opts-visitor.h b/include/qapi/opts-visitor.h
index 6462c96c2..fd48c14ec 100644
--- a/include/qapi/opts-visitor.h
+++ b/include/qapi/opts-visitor.h
@@ -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
diff --git a/include/qapi/qmp-input-visitor.h b/include/qapi/qmp-input-visitor.h
index f3ff5f3e9..3ed499cc4 100644
--- a/include/qapi/qmp-input-visitor.h
+++ b/include/qapi/qmp-input-visitor.h
@@ -19,12 +19,11 @@
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
diff --git a/include/qapi/qmp-output-visitor.h b/include/qapi/qmp-output-visitor.h
index 040fdda14..22667706a 100644
--- a/include/qapi/qmp-output-visitor.h
+++ b/include/qapi/qmp-output-visitor.h
@@ -19,12 +19,10 @@
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
diff --git a/include/qapi/qmp/dispatch.h b/include/qapi/qmp/dispatch.h
index 48c11b66d..495520994 100644
--- a/include/qapi/qmp/dispatch.h
+++ b/include/qapi/qmp/dispatch.h
@@ -11,14 +11,19 @@
*
*/
-#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
+
diff --git a/include/qapi/qmp/qerror.h b/include/qapi/qmp/qerror.h
index 6586c9fa6..d08652aaa 100644
--- a/include/qapi/qmp/qerror.h
+++ b/include/qapi/qmp/qerror.h
@@ -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"
diff --git a/include/qapi/qmp/types.h b/include/qapi/qmp/types.h
index 27cfbd84e..7782ec5a6 100644
--- a/include/qapi/qmp/types.h
+++ b/include/qapi/qmp/types.h
@@ -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 */
diff --git a/include/qapi/string-input-visitor.h b/include/qapi/string-input-visitor.h
index 33551340e..089243c09 100644
--- a/include/qapi/string-input-visitor.h
+++ b/include/qapi/string-input-visitor.h
@@ -17,11 +17,9 @@
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
diff --git a/include/qapi/string-output-visitor.h b/include/qapi/string-output-visitor.h
index 268dfe998..d99717f65 100644
--- a/include/qapi/string-output-visitor.h
+++ b/include/qapi/string-output-visitor.h
@@ -17,19 +17,10 @@
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
diff --git a/include/qapi/visitor-impl.h b/include/qapi/visitor-impl.h
index 8bd47ee4b..2bd8f292b 100644
--- a/include/qapi/visitor-impl.h
+++ b/include/qapi/visitor-impl.h
@@ -14,106 +14,55 @@
#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
diff --git a/include/qapi/visitor.h b/include/qapi/visitor.h
index 6c77a913d..9a8d0105f 100644
--- a/include/qapi/visitor.h
+++ b/include/qapi/visitor.h
@@ -11,230 +11,13 @@
* 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
diff --git a/include/qemu-common.h b/include/qemu-common.h
index 9e8b0bd99..163bcbb86 100644
--- a/include/qemu-common.h
+++ b/include/qemu-common.h
@@ -14,13 +14,32 @@
#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,
diff --git a/include/qemu/acl.h b/include/qemu/acl.h
index 7c44119a4..116487e28 100644
--- a/include/qemu/acl.h
+++ b/include/qemu/acl.h
@@ -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:
+ */
diff --git a/include/qemu/atomic.h b/include/qemu/atomic.h
index 43b06458f..5bc4d6cc4 100644
--- a/include/qemu/atomic.h
+++ b/include/qemu/atomic.h
@@ -12,54 +12,14 @@
* 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 */
@@ -76,18 +36,7 @@
#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; \
})
@@ -107,23 +56,13 @@
__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; \
})
@@ -145,7 +84,7 @@
#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; \
@@ -162,7 +101,7 @@
#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; \
})
@@ -179,7 +118,7 @@
#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; \
})
@@ -188,7 +127,7 @@
#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; \
@@ -406,4 +345,4 @@
#define atomic_or(ptr, n) ((void) __sync_fetch_and_or(ptr, n))
#endif /* __ATOMIC_RELAXED */
-#endif /* QEMU_ATOMIC_H */
+#endif /* __QEMU_ATOMIC_H */
diff --git a/include/qemu/base64.h b/include/qemu/base64.h
index 815d85267..793708dc3 100644
--- a/include/qemu/base64.h
+++ b/include/qemu/base64.h
@@ -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__ */
diff --git a/include/qemu/bcd.h b/include/qemu/bcd.h
index dfebacf1f..b4c9b64b8 100644
--- a/include/qemu/bcd.h
+++ b/include/qemu/bcd.h
@@ -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)
diff --git a/include/qemu/bitmap.h b/include/qemu/bitmap.h
index ec5146f84..0e33fa5d9 100644
--- a/include/qemu/bitmap.h
+++ b/include/qemu/bitmap.h
@@ -12,6 +12,7 @@
#ifndef BITMAP_H
#define BITMAP_H
+#include <glib.h>
#include "qemu/bitops.h"
diff --git a/include/qemu/bitops.h b/include/qemu/bitops.h
index 98fb005ab..755fdd129 100644
--- a/include/qemu/bitops.h
+++ b/include/qemu/bitops.h
@@ -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
diff --git a/include/qemu/bswap.h b/include/qemu/bswap.h
index 09c78fd28..ce3c42e4d 100644
--- a/include/qemu/bswap.h
+++ b/include/qemu/bswap.h
@@ -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.
*/
diff --git a/include/qemu/buffer.h b/include/qemu/buffer.h
index b2ead1f05..dead9b77e 100644
--- a/include/qemu/buffer.h
+++ b/include/qemu/buffer.h
@@ -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__ */
diff --git a/include/qemu/compiler.h b/include/qemu/compiler.h
index 338d3a65b..8f1cc7ba6 100644
--- a/include/qemu/compiler.h
+++ b/include/qemu/compiler.h
@@ -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)
diff --git a/include/qemu/config-file.h b/include/qemu/config-file.h
index 8d4b2b6d9..3b8ecb095 100644
--- a/include/qemu/config-file.h
+++ b/include/qemu/config-file.h
@@ -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 */
diff --git a/include/qemu/coroutine.h b/include/qemu/coroutine.h
index ac8d4c9cc..305fe76c2 100644
--- a/include/qemu/coroutine.h
+++ b/include/qemu/coroutine.h
@@ -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;
/**
diff --git a/include/qemu/coroutine_int.h b/include/qemu/coroutine_int.h
index 581a7f514..42d683840 100644
--- a/include/qemu/coroutine_int.h
+++ b/include/qemu/coroutine_int.h
@@ -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);
diff --git a/include/qemu/cutils.h b/include/qemu/cutils.h
index 3e4ea236f..db7adadcf 100644
--- a/include/qemu/cutils.h
+++ b/include/qemu/cutils.h
@@ -1,5 +1,5 @@
#ifndef QEMU_CUTILS_H
-#define QEMU_CUTILS_H
+#define QEMU_CUTILS_H 1
#include "qemu/fprintf-fn.h"
diff --git a/include/qemu/error-report.h b/include/qemu/error-report.h
index 499ec8b12..7a2a363fb 100644
--- a/include/qemu/error-report.h
+++ b/include/qemu/error-report.h
@@ -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
index 4e9fd1b5e..000000000
--- a/include/qemu/fifo32.h
+++ /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 */
diff --git a/include/qemu/fifo8.h b/include/qemu/fifo8.h
index 24b364462..882078066 100644
--- a/include/qemu/fifo8.h
+++ b/include/qemu/fifo8.h
@@ -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 */
diff --git a/include/qemu/fprintf-fn.h b/include/qemu/fprintf-fn.h
index 9068a960b..b6bad35b1 100644
--- a/include/qemu/fprintf-fn.h
+++ b/include/qemu/fprintf-fn.h
@@ -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);
diff --git a/include/qemu/hbitmap.h b/include/qemu/hbitmap.h
index 8ab721e5a..e29188c0a 100644
--- a/include/qemu/hbitmap.h
+++ b/include/qemu/hbitmap.h
@@ -10,7 +10,7 @@
*/
#ifndef HBITMAP_H
-#define HBITMAP_H
+#define HBITMAP_H 1
#include "bitops.h"
#include "host-utils.h"
diff --git a/include/qemu/help_option.h b/include/qemu/help_option.h
index 328d2a89f..e39a66e77 100644
--- a/include/qemu/help_option.h
+++ b/include/qemu/help_option.h
@@ -1,5 +1,5 @@
#ifndef QEMU_HELP_OPTION_H
-#define QEMU_HELP_OPTION_H
+#define QEMU_HELP_OPTION_H 1
/**
* is_help_option:
diff --git a/include/qemu/host-utils.h b/include/qemu/host-utils.h
index 46187bbc7..1cdae0d0e 100644
--- a/include/qemu/host-utils.h
+++ b/include/qemu/host-utils.h
@@ -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));
diff --git a/include/qemu/id.h b/include/qemu/id.h
index 40c70103e..7d90335af 100644
--- a/include/qemu/id.h
+++ b/include/qemu/id.h
@@ -1,5 +1,5 @@
#ifndef QEMU_ID_H
-#define QEMU_ID_H
+#define QEMU_ID_H 1
typedef enum IdSubSystems {
ID_QDEV,
diff --git a/include/qemu/log.h b/include/qemu/log.h
index 00bf37fc0..c52f136ac 100644
--- a/include/qemu/log.h
+++ b/include/qemu/log.h
@@ -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);
diff --git a/include/qemu/main-loop.h b/include/qemu/main-loop.h
index 470f600bb..19b5de3dd 100644
--- a/include/qemu/main-loop.h
+++ b/include/qemu/main-loop.h
@@ -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 (...) {
diff --git a/include/qemu/mmap-alloc.h b/include/qemu/mmap-alloc.h
index 933c024ac..0899b2f01 100644
--- a/include/qemu/mmap-alloc.h
+++ b/include/qemu/mmap-alloc.h
@@ -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"
diff --git a/include/qemu/option.h b/include/qemu/option.h
index 1f9e3f939..8542d2dfd 100644
--- a/include/qemu/option.h
+++ b/include/qemu/option.h
@@ -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"
diff --git a/include/qemu/option_int.h b/include/qemu/option_int.h
index 26b1d9e4d..6432c1a8c 100644
--- a/include/qemu/option_int.h
+++ b/include/qemu/option_int.h
@@ -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"
diff --git a/include/qemu/osdep.h b/include/qemu/osdep.h
index 9e9fa6154..af83b1a5a 100644
--- a/include/qemu/osdep.h
+++ b/include/qemu/osdep.h
@@ -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);
diff --git a/include/qemu/path.h b/include/qemu/path.h
index c6292a970..ed5fee086 100644
--- a/include/qemu/path.h
+++ b/include/qemu/path.h
@@ -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
index 8b2570283..000000000
--- a/include/qemu/processor.h
+++ /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
index 54ece760d..000000000
--- a/include/qemu/qdist.h
+++ /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
index 311139b85..000000000
--- a/include/qemu/qht.h
+++ /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 */
diff --git a/include/qemu/queue.h b/include/qemu/queue.h
index c2b6c8149..f781aa20a 100644
--- a/include/qemu/queue.h
+++ b/include/qemu/queue.h
@@ -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_ */
diff --git a/include/qemu/range.h b/include/qemu/range.h
index f28f0c182..c903eb574 100644
--- a/include/qemu/range.h
+++ b/include/qemu/range.h
@@ -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
@@ -26,111 +6,32 @@
/*
* 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
diff --git a/include/qemu/ratelimit.h b/include/qemu/ratelimit.h
index 8da123257..d413a4a69 100644
--- a/include/qemu/ratelimit.h
+++ b/include/qemu/ratelimit.h
@@ -12,62 +12,37 @@
*/
#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
diff --git a/include/qemu/rcu.h b/include/qemu/rcu.h
index 83ae2808b..56d3a682a 100644
--- a/include/qemu/rcu.h
+++ b/include/qemu/rcu.h
@@ -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"
diff --git a/include/qemu/rcu_queue.h b/include/qemu/rcu_queue.h
index 01be77407..3aca7a57e 100644
--- a/include/qemu/rcu_queue.h
+++ b/include/qemu/rcu_queue.h
@@ -131,4 +131,4 @@ extern "C" {
#ifdef __cplusplus
}
#endif
-#endif /* QEMU_RCU_QUEUE_H */
+#endif /* QEMU_RCU_QUEUE.H */
diff --git a/include/qemu/readline.h b/include/qemu/readline.h
index c08cf7400..49efe4e39 100644
--- a/include/qemu/readline.h
+++ b/include/qemu/readline.h
@@ -60,4 +60,4 @@ ReadLineState *readline_init(ReadLinePrintfFunc *printf_func,
void *opaque,
ReadLineCompletionFunc *completion_finder);
-#endif /* READLINE_H */
+#endif /* !READLINE_H */
diff --git a/include/qemu/seqlock.h b/include/qemu/seqlock.h
index 2e2be4c4f..70b01fd60 100644
--- a/include/qemu/seqlock.h
+++ b/include/qemu/seqlock.h
@@ -10,39 +10,46 @@
* 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)
diff --git a/include/qemu/sockets.h b/include/qemu/sockets.h
index 9eb24707d..1bd92180f 100644
--- a/include/qemu/sockets.h
+++ b/include/qemu/sockets.h
@@ -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 */
diff --git a/include/qemu/thread-posix.h b/include/qemu/thread-posix.h
index aa03567e5..eb5c7a1da 100644
--- a/include/qemu/thread-posix.h
+++ b/include/qemu/thread-posix.h
@@ -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 {
diff --git a/include/qemu/thread-win32.h b/include/qemu/thread-win32.h
index c7ce8dcd4..385ff5f76 100644
--- a/include/qemu/thread-win32.h
+++ b/include/qemu/thread-win32.h
@@ -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;
diff --git a/include/qemu/thread.h b/include/qemu/thread.h
index 31237e93e..bdae6dfdb 100644
--- a/include/qemu/thread.h
+++ b/include/qemu/thread.h
@@ -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
diff --git a/include/qemu/timer.h b/include/qemu/timer.h
index 309f3d09e..471969a24 100644
--- a/include/qemu/timer.h
+++ b/include/qemu/timer.h
@@ -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
diff --git a/include/qemu/typedefs.h b/include/qemu/typedefs.h
index b113fcf15..1dcf6f5d5 100644
--- a/include/qemu/typedefs.h
+++ b/include/qemu/typedefs.h
@@ -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;
diff --git a/include/qemu/unicode.h b/include/qemu/unicode.h
index 71c72db46..d8731652d 100644
--- a/include/qemu/unicode.h
+++ b/include/qemu/unicode.h
@@ -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);
diff --git a/include/migration/qjson.h b/include/qjson.h
index 2978b5f37..7c54fdf0a 100644
--- a/include/migration/qjson.h
+++ b/include/qjson.h
@@ -13,10 +13,10 @@
#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);
diff --git a/include/qom/cpu.h b/include/qom/cpu.h
index ce0c406f2..b7a10f791 100644
--- a/include/qom/cpu.h
+++ b/include/qom/cpu.h
@@ -24,10 +24,8 @@
#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
diff --git a/include/qom/object.h b/include/qom/object.h
index 5ecc2d166..21bb5ff14 100644
--- a/include/qom/object.h
+++ b/include/qom/object.h
@@ -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
diff --git a/include/standard-headers/linux/pci_regs.h b/include/standard-headers/linux/pci_regs.h
index 404095124..1becea86c 100644
--- a/include/standard-headers/linux/pci_regs.h
+++ b/include/standard-headers/linux/pci_regs.h
@@ -670,8 +670,7 @@
#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
@@ -947,21 +946,4 @@
#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 */
diff --git a/include/standard-headers/linux/virtio_config.h b/include/standard-headers/linux/virtio_config.h
index b30d0cb0c..bcc445b3d 100644
--- a/include/standard-headers/linux/virtio_config.h
+++ b/include/standard-headers/linux/virtio_config.h
@@ -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
diff --git a/include/sysemu/accel.h b/include/sysemu/accel.h
index 15944c152..a74b2faf5 100644
--- a/include/sysemu/accel.h
+++ b/include/sysemu/accel.h
@@ -56,6 +56,6 @@ typedef struct AccelClass {
extern int tcg_tb_size;
-void configure_accelerator(MachineState *ms);
+int configure_accelerator(MachineState *ms);
#endif
diff --git a/include/sysemu/arch_init.h b/include/sysemu/arch_init.h
index d690dfabd..c38892fec 100644
--- a/include/sysemu/arch_init.h
+++ b/include/sysemu/arch_init.h
@@ -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);
diff --git a/include/sysemu/balloon.h b/include/sysemu/balloon.h
index af49e19c7..3f976b49e 100644
--- a/include/sysemu/balloon.h
+++ b/include/sysemu/balloon.h
@@ -11,8 +11,8 @@
*
*/
-#ifndef QEMU_BALLOON_H
-#define QEMU_BALLOON_H
+#ifndef _QEMU_BALLOON_H
+#define _QEMU_BALLOON_H
#include "qapi-types.h"
diff --git a/include/sysemu/block-backend.h b/include/sysemu/block-backend.h
index 2da4905d1..c62b6fe96 100644
--- a/include/sysemu/block-backend.h
+++ b/include/sysemu/block-backend.h
@@ -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
diff --git a/include/sysemu/bt.h b/include/sysemu/bt.h
index ddb05cd10..2bc6d53cc 100644
--- a/include/sysemu/bt.h
+++ b/include/sysemu/bt.h
@@ -1,5 +1,5 @@
-#ifndef SYSEMU_BT_H
-#define SYSEMU_BT_H
+#ifndef BT_HOST_H
+#define BT_HOST_H
/* BT HCI info */
diff --git a/include/sysemu/char.h b/include/sysemu/char.h
index ee7e55468..307fd8fde 100644
--- a/include/sysemu/char.h
+++ b/include/sysemu/char.h
@@ -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);
diff --git a/include/sysemu/cpus.h b/include/sysemu/cpus.h
index fe992a894..3d1e5ba1e 100644
--- a/include/sysemu/cpus.h
+++ b/include/sysemu/cpus.h
@@ -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);
diff --git a/include/sysemu/device_tree.h b/include/sysemu/device_tree.h
index e22e5bec9..705650aad 100644
--- a/include/sysemu/device_tree.h
+++ b/include/sysemu/device_tree.h
@@ -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__ */
diff --git a/include/sysemu/dma.h b/include/sysemu/dma.h
index 34c8eaf64..b0fbb9bb3 100644
--- a/include/sysemu/dma.h
+++ b/include/sysemu/dma.h
@@ -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);
diff --git a/include/sysemu/hostmem.h b/include/sysemu/hostmem.h
index 678232af4..a19801d20 100644
--- a/include/sysemu/hostmem.h
+++ b/include/sysemu/hostmem.h
@@ -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
diff --git a/include/sysemu/kvm.h b/include/sysemu/kvm.h
index c9c243631..0e18f15c9 100644
--- a/include/sysemu/kvm.h
+++ b/include/sysemu/kvm.h
@@ -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
diff --git a/include/sysemu/os-posix.h b/include/sysemu/os-posix.h
index 9c7dfdfbe..07e3e5ae9 100644
--- a/include/sysemu/os-posix.h
+++ b/include/sysemu/os-posix.h
@@ -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>
diff --git a/include/sysemu/rng-random.h b/include/sysemu/rng-random.h
index 38186fe83..4332772a2 100644
--- a/include/sysemu/rng-random.h
+++ b/include/sysemu/rng-random.h
@@ -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
diff --git a/include/sysemu/sysemu.h b/include/sysemu/sysemu.h
index ee7c7608e..38fb3cad3 100644
--- a/include/sysemu/sysemu.h
+++ b/include/sysemu/sysemu.h
@@ -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;
diff --git a/include/sysemu/tpm_backend.h b/include/sysemu/tpm_backend.h
index b58f52d39..e3ec80020 100644
--- a/include/sysemu/tpm_backend.h
+++ b/include/sysemu/tpm_backend.h
@@ -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"
diff --git a/include/sysemu/tpm_backend_int.h b/include/sysemu/tpm_backend_int.h
index 00639dd7d..40f693a0c 100644
--- a/include/sysemu/tpm_backend_int.h
+++ b/include/sysemu/tpm_backend_int.h
@@ -19,8 +19,10 @@
* 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 */
diff --git a/include/sysemu/xen-mapcache.h b/include/sysemu/xen-mapcache.h
index b8c93b9bc..c849489fb 100644
--- a/include/sysemu/xen-mapcache.h
+++ b/include/sysemu/xen-mapcache.h
@@ -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 */
diff --git a/include/trace-tcg.h b/include/trace-tcg.h
index edab4b159..6f6bdbb44 100644
--- a/include/trace-tcg.h
+++ b/include/trace-tcg.h
@@ -4,4 +4,4 @@
#include "trace/generated-tcg-tracers.h"
#include "trace/generated-events.h"
-#endif /* TRACE_TCG_H */
+#endif /* TRACE_TCG_H */
diff --git a/include/trace.h b/include/trace.h
index 9a01e4454..44a1f1f8c 100644
--- a/include/trace.h
+++ b/include/trace.h
@@ -4,4 +4,4 @@
#include "trace/generated-tracers.h"
#include "trace/generated-events.h"
-#endif /* TRACE_H */
+#endif /* TRACE_H */
diff --git a/include/ui/console.h b/include/ui/console.h
index 2703a3aa5..d5a88d93e 100644
--- a/include/ui/console.h
+++ b/include/ui/console.h
@@ -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
diff --git a/include/ui/gtk.h b/include/ui/gtk.h
index 42ca0fea8..2bf60f3ec 100644
--- a/include/ui/gtk.h
+++ b/include/ui/gtk.h
@@ -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,
diff --git a/include/ui/qemu-spice.h b/include/ui/qemu-spice.h
index 75e12396b..aa2436355 100644
--- a/include/ui/qemu-spice.h
+++ b/include/ui/qemu-spice.h
@@ -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)
diff --git a/include/ui/sdl2.h b/include/ui/sdl2.h
index 683bb6af2..3f0b57bb1 100644
--- a/include/ui/sdl2.h
+++ b/include/ui/sdl2.h
@@ -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,
diff --git a/io/channel-buffer.c b/io/channel-buffer.c
index 43d795976..3e5117bf2 100644
--- a/io/channel-buffer.c
+++ b/io/channel-buffer.c
@@ -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;
diff --git a/io/channel-socket.c b/io/channel-socket.c
index 196a4f18f..ca8bc20b1 100644
--- a/io/channel-socket.c
+++ b/io/channel-socket.c
@@ -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
diff --git a/io/channel-websock.c b/io/channel-websock.c
index 533bd4b3b..d5a4ed3f9 100644
--- a/io/channel-websock.c
+++ b/io/channel-websock.c
@@ -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"
diff --git a/io/channel.c b/io/channel.c
index 923c4651c..692eb179b 100644
--- a/io/channel.c
+++ b/io/channel.c
@@ -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
index d064665f4..000000000
--- a/io/trace-events
+++ /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"
diff --git a/ioport.c b/ioport.c
index 94e08ab65..7a84d5444 100644
--- 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;
diff --git a/kvm-all.c b/kvm-all.c
index ebf35b0c5..f9ae8f9bf 100644
--- 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"
@@ -61,12 +61,6 @@
#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();
}
}
diff --git a/kvm-stub.c b/kvm-stub.c
index 64e23f6be..b962b2483 100644
--- a/kvm-stub.c
+++ b/kvm-stub.c
@@ -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;
diff --git a/linux-headers/asm-arm/unistd.h b/linux-headers/asm-arm/unistd.h
index ceb5450c8..3f6f72792 100644
--- a/linux-headers/asm-arm/unistd.h
+++ b/linux-headers/asm-arm/unistd.h
@@ -418,8 +418,6 @@
#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.
diff --git a/linux-headers/asm-arm64/unistd.h b/linux-headers/asm-arm64/unistd.h
index 043d17a21..1caadc24e 100644
--- a/linux-headers/asm-arm64/unistd.h
+++ b/linux-headers/asm-arm64/unistd.h
@@ -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>
diff --git a/linux-headers/asm-powerpc/unistd.h b/linux-headers/asm-powerpc/unistd.h
index 1e66eba4c..cd92d982f 100644
--- a/linux-headers/asm-powerpc/unistd.h
+++ b/linux-headers/asm-powerpc/unistd.h
@@ -390,7 +390,5 @@
#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_ */
diff --git a/linux-headers/asm-s390/kvm.h b/linux-headers/asm-s390/kvm.h
index 09ae5dc2e..a59499be0 100644
--- a/linux-headers/asm-s390/kvm.h
+++ b/linux-headers/asm-s390/kvm.h
@@ -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.
diff --git a/linux-headers/asm-s390/unistd.h b/linux-headers/asm-s390/unistd.h
index 8a404fd3a..885837ed5 100644
--- a/linux-headers/asm-s390/unistd.h
+++ b/linux-headers/asm-s390/unistd.h
@@ -311,9 +311,7 @@
#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
diff --git a/linux-headers/asm-x86/kvm.h b/linux-headers/asm-x86/kvm.h
index 739c0c594..cd54147cb 100644
--- a/linux-headers/asm-x86/kvm.h
+++ b/linux-headers/asm-x86/kvm.h
@@ -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 {
diff --git a/linux-headers/asm-x86/unistd_x32.h b/linux-headers/asm-x86/unistd_x32.h
index 0230779a8..8f77ee868 100644
--- a/linux-headers/asm-x86/unistd_x32.h
+++ b/linux-headers/asm-x86/unistd_x32.h
@@ -306,9 +306,7 @@
#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)
diff --git a/linux-headers/linux/kvm.h b/linux-headers/linux/kvm.h
index e60e21ba2..3bae71a87 100644
--- a/linux-headers/linux/kvm.h
+++ b/linux-headers/linux/kvm.h
@@ -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
diff --git a/linux-user/Makefile.objs b/linux-user/Makefile.objs
index 8c9305810..fd5021788 100644
--- a/linux-user/Makefile.objs
+++ b/linux-user/Makefile.objs
@@ -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
diff --git a/linux-user/aarch64/syscall_nr.h b/linux-user/aarch64/syscall_nr.h
index a3c9a3b67..59511d855 100644
--- a/linux-user/aarch64/syscall_nr.h
+++ b/linux-user/aarch64/syscall_nr.h
@@ -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
diff --git a/linux-user/aarch64/target_cpu.h b/linux-user/aarch64/target_cpu.h
index 777ce29f1..b5593dc5a 100644
--- a/linux-user/aarch64/target_cpu.h
+++ b/linux-user/aarch64/target_cpu.h
@@ -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)
{
diff --git a/linux-user/aarch64/target_signal.h b/linux-user/aarch64/target_signal.h
index e66367cac..e8c677de1 100644
--- a/linux-user/aarch64/target_signal.h
+++ b/linux-user/aarch64/target_signal.h
@@ -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 */
diff --git a/linux-user/aarch64/target_structs.h b/linux-user/aarch64/target_structs.h
index a4998a749..21c1f2c07 100644
--- a/linux-user/aarch64/target_structs.h
+++ b/linux-user/aarch64/target_structs.h
@@ -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. */
diff --git a/linux-user/aarch64/target_syscall.h b/linux-user/aarch64/target_syscall.h
index 1b62953ee..f45801804 100644
--- a/linux-user/aarch64/target_syscall.h
+++ b/linux-user/aarch64/target_syscall.h
@@ -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 */
diff --git a/linux-user/alpha/target_cpu.h b/linux-user/alpha/target_cpu.h
index ad124da7c..42562452b 100644
--- a/linux-user/alpha/target_cpu.h
+++ b/linux-user/alpha/target_cpu.h
@@ -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)
{
diff --git a/linux-user/alpha/target_signal.h b/linux-user/alpha/target_signal.h
index f1ed00d50..d3822da60 100644
--- a/linux-user/alpha/target_signal.h
+++ b/linux-user/alpha/target_signal.h
@@ -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 */
diff --git a/linux-user/alpha/target_structs.h b/linux-user/alpha/target_structs.h
index db2bfe287..50e7708ff 100644
--- a/linux-user/alpha/target_structs.h
+++ b/linux-user/alpha/target_structs.h
@@ -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. */
diff --git a/linux-user/alpha/target_syscall.h b/linux-user/alpha/target_syscall.h
index b580fc5b3..3db4b16f6 100644
--- a/linux-user/alpha/target_syscall.h
+++ b/linux-user/alpha/target_syscall.h
@@ -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 */
diff --git a/linux-user/arm/nwfpe/fpa11.h b/linux-user/arm/nwfpe/fpa11.h
index d459c5da0..0b072843d 100644
--- a/linux-user/arm/nwfpe/fpa11.h
+++ b/linux-user/arm/nwfpe/fpa11.h
@@ -18,10 +18,11 @@
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)
diff --git a/linux-user/arm/nwfpe/fpopcode.h b/linux-user/arm/nwfpe/fpopcode.h
index 06cd90985..1b1137f3c 100644
--- a/linux-user/arm/nwfpe/fpopcode.h
+++ b/linux-user/arm/nwfpe/fpopcode.h
@@ -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
diff --git a/linux-user/arm/nwfpe/fpsr.h b/linux-user/arm/nwfpe/fpsr.h
index 8c978f0b8..859dcd589 100644
--- a/linux-user/arm/nwfpe/fpsr.h
+++ b/linux-user/arm/nwfpe/fpsr.h
@@ -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
diff --git a/linux-user/arm/target_cpu.h b/linux-user/arm/target_cpu.h
index d88821915..6832262e3 100644
--- a/linux-user/arm/target_cpu.h
+++ b/linux-user/arm/target_cpu.h
@@ -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)
{
diff --git a/linux-user/arm/target_signal.h b/linux-user/arm/target_signal.h
index cbbeb09f4..2b3281312 100644
--- a/linux-user/arm/target_signal.h
+++ b/linux-user/arm/target_signal.h
@@ -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 */
diff --git a/linux-user/arm/target_structs.h b/linux-user/arm/target_structs.h
index 0bf034cc2..f3c85d4e1 100644
--- a/linux-user/arm/target_structs.h
+++ b/linux-user/arm/target_structs.h
@@ -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. */
diff --git a/linux-user/arm/target_syscall.h b/linux-user/arm/target_syscall.h
index cd021ff59..ea863db0b 100644
--- a/linux-user/arm/target_syscall.h
+++ b/linux-user/arm/target_syscall.h
@@ -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 */
diff --git a/linux-user/cris/target_cpu.h b/linux-user/cris/target_cpu.h
index c43aac62f..4d787e5ff 100644
--- a/linux-user/cris/target_cpu.h
+++ b/linux-user/cris/target_cpu.h
@@ -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)
{
diff --git a/linux-user/cris/target_signal.h b/linux-user/cris/target_signal.h
index 664621bbc..5611840f8 100644
--- a/linux-user/cris/target_signal.h
+++ b/linux-user/cris/target_signal.h
@@ -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 */
diff --git a/linux-user/cris/target_structs.h b/linux-user/cris/target_structs.h
index 76f965325..e4a1ffb3c 100644
--- a/linux-user/cris/target_structs.h
+++ b/linux-user/cris/target_structs.h
@@ -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. */
diff --git a/linux-user/cris/target_syscall.h b/linux-user/cris/target_syscall.h
index 29d69009f..2957b0d6a 100644
--- a/linux-user/cris/target_syscall.h
+++ b/linux-user/cris/target_syscall.h
@@ -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"
diff --git a/linux-user/elfload.c b/linux-user/elfload.c
index f807baf38..e47caff7a 100644
--- a/linux-user/elfload.c
+++ b/linux-user/elfload.c
@@ -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
diff --git a/linux-user/errno_defs.h b/linux-user/errno_defs.h
index 65522c451..8a1cf76cd 100644
--- a/linux-user/errno_defs.h
+++ b/linux-user/errno_defs.h
@@ -139,20 +139,3 @@
/* 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 */
diff --git a/linux-user/flatload.c b/linux-user/flatload.c
index 42d1079a2..f9139c399 100644
--- a/linux-user/flatload.c
+++ b/linux-user/flatload.c
@@ -34,10 +34,11 @@
/****************************************************************************/
#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
index 64f75cef4..000000000
--- a/linux-user/host/aarch64/hostdep.h
+++ /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
index 58a2329b3..000000000
--- a/linux-user/host/aarch64/safe-syscall.inc.S
+++ /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
index 5c1ae6012..000000000
--- a/linux-user/host/arm/hostdep.h
+++ /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
index 88c495850..000000000
--- a/linux-user/host/arm/safe-syscall.inc.S
+++ /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
index d834bd80e..000000000
--- a/linux-user/host/i386/hostdep.h
+++ /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
index 9e58fc650..000000000
--- a/linux-user/host/i386/safe-syscall.inc.S
+++ /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
index 263bf7658..000000000
--- a/linux-user/host/ia64/hostdep.h
+++ /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
index ba111d75c..000000000
--- a/linux-user/host/mips/hostdep.h
+++ /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
index 23d8bd9d4..000000000
--- a/linux-user/host/ppc/hostdep.h
+++ /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
index 0b0f5f782..000000000
--- a/linux-user/host/ppc64/hostdep.h
+++ /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
index d30050a67..000000000
--- a/linux-user/host/ppc64/safe-syscall.inc.S
+++ /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
index afcba5a16..000000000
--- a/linux-user/host/s390/hostdep.h
+++ /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
index 6f9da9c60..000000000
--- a/linux-user/host/s390x/hostdep.h
+++ /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
index f1b446abf..000000000
--- a/linux-user/host/s390x/safe-syscall.inc.S
+++ /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
index 391ad923c..000000000
--- a/linux-user/host/sparc/hostdep.h
+++ /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
index ce3968fca..000000000
--- a/linux-user/host/sparc64/hostdep.h
+++ /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
index 2c2d6d37d..000000000
--- a/linux-user/host/x32/hostdep.h
+++ /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
index 3b4259633..000000000
--- a/linux-user/host/x86_64/hostdep.h
+++ /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
index f36992daa..000000000
--- a/linux-user/host/x86_64/safe-syscall.inc.S
+++ /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
diff --git a/linux-user/i386/target_cpu.h b/linux-user/i386/target_cpu.h
index 7fbcf9bb5..58f86454d 100644
--- a/linux-user/i386/target_cpu.h
+++ b/linux-user/i386/target_cpu.h
@@ -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) */
diff --git a/linux-user/i386/target_signal.h b/linux-user/i386/target_signal.h
index 837e90fc4..9baf7fbeb 100644
--- a/linux-user/i386/target_signal.h
+++ b/linux-user/i386/target_signal.h
@@ -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 */
diff --git a/linux-user/i386/target_structs.h b/linux-user/i386/target_structs.h
index 25388a7fd..65f535e16 100644
--- a/linux-user/i386/target_structs.h
+++ b/linux-user/i386/target_structs.h
@@ -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. */
diff --git a/linux-user/i386/target_syscall.h b/linux-user/i386/target_syscall.h
index b4e895fd9..0ac84dc02 100644
--- a/linux-user/i386/target_syscall.h
+++ b/linux-user/i386/target_syscall.h
@@ -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 */
diff --git a/linux-user/ioctls.h b/linux-user/ioctls.h
index 7e2c133ba..e67265510 100644
--- a/linux-user/ioctls.h
+++ b/linux-user/ioctls.h
@@ -76,39 +76,10 @@
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
@@ -120,7 +91,7 @@
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)))
@@ -351,15 +322,11 @@
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)))
diff --git a/linux-user/linux_loop.h b/linux-user/linux_loop.h
index c69fea11e..8974caa9d 100644
--- a/linux-user/linux_loop.h
+++ b/linux-user/linux_loop.h
@@ -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
diff --git a/linux-user/m68k/target_cpu.h b/linux-user/m68k/target_cpu.h
index cc0bfc298..bb4d3fabe 100644
--- a/linux-user/m68k/target_cpu.h
+++ b/linux-user/m68k/target_cpu.h
@@ -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)
{
diff --git a/linux-user/m68k/target_signal.h b/linux-user/m68k/target_signal.h
index 9d2d7343f..479758a42 100644
--- a/linux-user/m68k/target_signal.h
+++ b/linux-user/m68k/target_signal.h
@@ -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 */
diff --git a/linux-user/m68k/target_structs.h b/linux-user/m68k/target_structs.h
index a00367654..de257c97d 100644
--- a/linux-user/m68k/target_structs.h
+++ b/linux-user/m68k/target_structs.h
@@ -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. */
diff --git a/linux-user/m68k/target_syscall.h b/linux-user/m68k/target_syscall.h
index db2be4f10..97a4cc0cb 100644
--- a/linux-user/m68k/target_syscall.h
+++ b/linux-user/m68k/target_syscall.h
@@ -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 */
diff --git a/linux-user/main.c b/linux-user/main.c
index f2f4d2f05..5f3ec9747 100644
--- a/linux-user/main.c
+++ b/linux-user/main.c
@@ -17,25 +17,20 @@
* 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;
diff --git a/linux-user/microblaze/target_cpu.h b/linux-user/microblaze/target_cpu.h
index 7dd979f96..c6386ea9e 100644
--- a/linux-user/microblaze/target_cpu.h
+++ b/linux-user/microblaze/target_cpu.h
@@ -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)
{
diff --git a/linux-user/microblaze/target_signal.h b/linux-user/microblaze/target_signal.h
index de2b0f49d..3d1f7a723 100644
--- a/linux-user/microblaze/target_signal.h
+++ b/linux-user/microblaze/target_signal.h
@@ -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 */
diff --git a/linux-user/microblaze/target_structs.h b/linux-user/microblaze/target_structs.h
index 70dbdb610..325e2f6d4 100644
--- a/linux-user/microblaze/target_structs.h
+++ b/linux-user/microblaze/target_structs.h
@@ -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. */
diff --git a/linux-user/microblaze/target_syscall.h b/linux-user/microblaze/target_syscall.h
index 0b6980c89..3c1ed27c0 100644
--- a/linux-user/microblaze/target_syscall.h
+++ b/linux-user/microblaze/target_syscall.h
@@ -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"
diff --git a/linux-user/mips/target_cpu.h b/linux-user/mips/target_cpu.h
index 200292031..19b885500 100644
--- a/linux-user/mips/target_cpu.h
+++ b/linux-user/mips/target_cpu.h
@@ -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)
{
diff --git a/linux-user/mips/target_signal.h b/linux-user/mips/target_signal.h
index 8dd27cef3..6e1dc8b6e 100644
--- a/linux-user/mips/target_signal.h
+++ b/linux-user/mips/target_signal.h
@@ -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 */
diff --git a/linux-user/mips/target_structs.h b/linux-user/mips/target_structs.h
index fbd995581..16021e8a9 100644
--- a/linux-user/mips/target_structs.h
+++ b/linux-user/mips/target_structs.h
@@ -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. */
diff --git a/linux-user/mips/target_syscall.h b/linux-user/mips/target_syscall.h
index 2b4f39072..68db160e5 100644
--- a/linux-user/mips/target_syscall.h
+++ b/linux-user/mips/target_syscall.h
@@ -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 */
diff --git a/linux-user/mips64/target_signal.h b/linux-user/mips64/target_signal.h
index 67ef5a18f..5fb6a2ccf 100644
--- a/linux-user/mips64/target_signal.h
+++ b/linux-user/mips64/target_signal.h
@@ -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 */
diff --git a/linux-user/mips64/target_syscall.h b/linux-user/mips64/target_syscall.h
index 8da9c1f9c..0e0c2d232 100644
--- a/linux-user/mips64/target_syscall.h
+++ b/linux-user/mips64/target_syscall.h
@@ -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 */
diff --git a/linux-user/mmap.c b/linux-user/mmap.c
index c4371d943..3519147bc 100644
--- a/linux-user/mmap.c
+++ b/linux-user/mmap.c
@@ -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>
diff --git a/linux-user/openrisc/target_cpu.h b/linux-user/openrisc/target_cpu.h
index a21ed1aff..32a46ac84 100644
--- a/linux-user/openrisc/target_cpu.h
+++ b/linux-user/openrisc/target_cpu.h
@@ -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)
{
diff --git a/linux-user/openrisc/target_signal.h b/linux-user/openrisc/target_signal.h
index 9f2c493f7..964aed69f 100644
--- a/linux-user/openrisc/target_signal.h
+++ b/linux-user/openrisc/target_signal.h
@@ -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 */
diff --git a/linux-user/openrisc/target_structs.h b/linux-user/openrisc/target_structs.h
index afbb7ad10..f4d560f57 100644
--- a/linux-user/openrisc/target_structs.h
+++ b/linux-user/openrisc/target_structs.h
@@ -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. */
diff --git a/linux-user/openrisc/target_syscall.h b/linux-user/openrisc/target_syscall.h
index 9d3380f9a..19aeffc95 100644
--- a/linux-user/openrisc/target_syscall.h
+++ b/linux-user/openrisc/target_syscall.h
@@ -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 */
diff --git a/linux-user/ppc/target_cpu.h b/linux-user/ppc/target_cpu.h
index 3aab3d185..26f4ba297 100644
--- a/linux-user/ppc/target_cpu.h
+++ b/linux-user/ppc/target_cpu.h
@@ -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)
{
diff --git a/linux-user/ppc/target_signal.h b/linux-user/ppc/target_signal.h
index 865c52f3e..a93b5cf1d 100644
--- a/linux-user/ppc/target_signal.h
+++ b/linux-user/ppc/target_signal.h
@@ -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 */
diff --git a/linux-user/ppc/target_structs.h b/linux-user/ppc/target_structs.h
index 6b1f5791a..2b8761310 100644
--- a/linux-user/ppc/target_structs.h
+++ b/linux-user/ppc/target_structs.h
@@ -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. */
diff --git a/linux-user/ppc/target_syscall.h b/linux-user/ppc/target_syscall.h
index a8662f485..35cab5946 100644
--- a/linux-user/ppc/target_syscall.h
+++ b/linux-user/ppc/target_syscall.h
@@ -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 */
diff --git a/linux-user/qemu.h b/linux-user/qemu.h
index bef465de4..26b0ba273 100644
--- a/linux-user/qemu.h
+++ b/linux-user/qemu.h
@@ -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
@@ -20,11 +19,6 @@
#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);
diff --git a/linux-user/s390x/target_cpu.h b/linux-user/s390x/target_cpu.h
index 87ea4d2d9..f10abe8e5 100644
--- a/linux-user/s390x/target_cpu.h
+++ b/linux-user/s390x/target_cpu.h
@@ -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)
{
diff --git a/linux-user/s390x/target_signal.h b/linux-user/s390x/target_signal.h
index 6f7b6abaf..b4816b040 100644
--- a/linux-user/s390x/target_signal.h
+++ b/linux-user/s390x/target_signal.h
@@ -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 */
diff --git a/linux-user/s390x/target_structs.h b/linux-user/s390x/target_structs.h
index cadff6db3..6b6f5b521 100644
--- a/linux-user/s390x/target_structs.h
+++ b/linux-user/s390x/target_structs.h
@@ -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 {
diff --git a/linux-user/s390x/target_syscall.h b/linux-user/s390x/target_syscall.h
index 8d4f609ea..02061efc7 100644
--- a/linux-user/s390x/target_syscall.h
+++ b/linux-user/s390x/target_syscall.h
@@ -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
index b5df6254a..000000000
--- a/linux-user/safe-syscall.S
+++ /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
diff --git a/linux-user/sh4/target_cpu.h b/linux-user/sh4/target_cpu.h
index 9d305d283..141856f84 100644
--- a/linux-user/sh4/target_cpu.h
+++ b/linux-user/sh4/target_cpu.h
@@ -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)
{
diff --git a/linux-user/sh4/target_signal.h b/linux-user/sh4/target_signal.h
index cbf23b6a3..e148da092 100644
--- a/linux-user/sh4/target_signal.h
+++ b/linux-user/sh4/target_signal.h
@@ -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 */
diff --git a/linux-user/sh4/target_structs.h b/linux-user/sh4/target_structs.h
index 3e832bf69..32b235e0b 100644
--- a/linux-user/sh4/target_structs.h
+++ b/linux-user/sh4/target_structs.h
@@ -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. */
diff --git a/linux-user/sh4/target_syscall.h b/linux-user/sh4/target_syscall.h
index 78d555712..9f3381bc9 100644
--- a/linux-user/sh4/target_syscall.h
+++ b/linux-user/sh4/target_syscall.h
@@ -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 */
diff --git a/linux-user/signal.c b/linux-user/signal.c
index 9a4d894e3..96e86c0a2 100644
--- a/linux-user/signal.c
+++ b/linux-user/signal.c
@@ -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);
+
+ if (oldset && segv_was_blocked) {
+ sigaddset(oldset, SIGSEGV);
+ }
- ts->signal_mask = *set;
+ 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;
+ 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;
+ }
- /*
- * 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);
}
diff --git a/linux-user/sparc/syscall_nr.h b/linux-user/sparc/syscall_nr.h
index e713c9d5f..732b1052a 100644
--- a/linux-user/sparc/syscall_nr.h
+++ b/linux-user/sparc/syscall_nr.h
@@ -179,9 +179,6 @@
#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 */
diff --git a/linux-user/sparc/target_cpu.h b/linux-user/sparc/target_cpu.h
index f2fe52620..4944d465a 100644
--- a/linux-user/sparc/target_cpu.h
+++ b/linux-user/sparc/target_cpu.h
@@ -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)
{
diff --git a/linux-user/sparc/target_signal.h b/linux-user/sparc/target_signal.h
index e445e2b46..c7de300cd 100644
--- a/linux-user/sparc/target_signal.h
+++ b/linux-user/sparc/target_signal.h
@@ -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 */
diff --git a/linux-user/sparc/target_structs.h b/linux-user/sparc/target_structs.h
index ee24c3b5f..c139e09a6 100644
--- a/linux-user/sparc/target_structs.h
+++ b/linux-user/sparc/target_structs.h
@@ -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. */
diff --git a/linux-user/sparc/target_syscall.h b/linux-user/sparc/target_syscall.h
index 326f674b4..a73fa6dae 100644
--- a/linux-user/sparc/target_syscall.h
+++ b/linux-user/sparc/target_syscall.h
@@ -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 */
diff --git a/linux-user/sparc64/target_signal.h b/linux-user/sparc64/target_signal.h
index 4449457ba..c7de300cd 100644
--- a/linux-user/sparc64/target_signal.h
+++ b/linux-user/sparc64/target_signal.h
@@ -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 */
diff --git a/linux-user/sparc64/target_structs.h b/linux-user/sparc64/target_structs.h
index 1808132b1..fc1729007 100644
--- a/linux-user/sparc64/target_structs.h
+++ b/linux-user/sparc64/target_structs.h
@@ -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. */
diff --git a/linux-user/sparc64/target_syscall.h b/linux-user/sparc64/target_syscall.h
index b7e3bf82f..eb827fcac 100644
--- a/linux-user/sparc64/target_syscall.h
+++ b/linux-user/sparc64/target_syscall.h
@@ -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 */
diff --git a/linux-user/strace.c b/linux-user/strace.c
index cc10dc470..0810c85fb 100644
--- a/linux-user/strace.c
+++ b/linux-user/strace.c
@@ -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 ) {
diff --git a/linux-user/strace.list b/linux-user/strace.list
index aa967a247..aa0cd735c 100644
--- a/linux-user/strace.list
+++ b/linux-user/strace.list
@@ -337,8 +337,7 @@
{ 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 },
@@ -1235,8 +1234,7 @@
{ 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 },
@@ -1293,10 +1291,10 @@
{ 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 },
diff --git a/linux-user/syscall.c b/linux-user/syscall.c
index ca06943f3..032d33886 100644
--- a/linux-user/syscall.c
+++ b/linux-user/syscall.c
@@ -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) {
@@ -3737,29 +2453,16 @@ 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;
- }
- }
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;
diff --git a/linux-user/syscall_defs.h b/linux-user/syscall_defs.h
index 783565463..9e2b3c200 100644
--- a/linux-user/syscall_defs.h
+++ b/linux-user/syscall_defs.h
@@ -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
diff --git a/linux-user/syscall_types.h b/linux-user/syscall_types.h
index af79fbf1d..1fd4ee0bf 100644
--- a/linux-user/syscall_types.h
+++ b/linux-user/syscall_types.h
@@ -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 */
diff --git a/linux-user/tilegx/syscall_nr.h b/linux-user/tilegx/syscall_nr.h
index 8e30cd1ae..87fb72c55 100644
--- a/linux-user/tilegx/syscall_nr.h
+++ b/linux-user/tilegx/syscall_nr.h
@@ -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.
diff --git a/linux-user/tilegx/target_cpu.h b/linux-user/tilegx/target_cpu.h
index 4878e01b0..c96e81d05 100644
--- a/linux-user/tilegx/target_cpu.h
+++ b/linux-user/tilegx/target_cpu.h
@@ -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)
{
diff --git a/linux-user/tilegx/target_signal.h b/linux-user/tilegx/target_signal.h
index f64551a8c..b595f985c 100644
--- a/linux-user/tilegx/target_signal.h
+++ b/linux-user/tilegx/target_signal.h
@@ -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 */
diff --git a/linux-user/tilegx/target_structs.h b/linux-user/tilegx/target_structs.h
index de8b1f2f4..7d3ff782f 100644
--- a/linux-user/tilegx/target_structs.h
+++ b/linux-user/tilegx/target_structs.h
@@ -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. */
diff --git a/linux-user/tilegx/target_syscall.h b/linux-user/tilegx/target_syscall.h
index d731acdaf..a938d4e90 100644
--- a/linux-user/tilegx/target_syscall.h
+++ b/linux-user/tilegx/target_syscall.h
@@ -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
index fc71f91cc..000000000
--- a/linux-user/trace-events
+++ /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
diff --git a/linux-user/uname.h b/linux-user/uname.h
index 450309421..cc62e76cc 100644
--- a/linux-user/uname.h
+++ b/linux-user/uname.h
@@ -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 */
diff --git a/linux-user/unicore32/target_cpu.h b/linux-user/unicore32/target_cpu.h
index d7d2e7b08..fb7908719 100644
--- a/linux-user/unicore32/target_cpu.h
+++ b/linux-user/unicore32/target_cpu.h
@@ -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)
{
diff --git a/linux-user/unicore32/target_signal.h b/linux-user/unicore32/target_signal.h
index c6496fb9e..7c442381a 100644
--- a/linux-user/unicore32/target_signal.h
+++ b/linux-user/unicore32/target_signal.h
@@ -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 */
diff --git a/linux-user/unicore32/target_structs.h b/linux-user/unicore32/target_structs.h
index fbd4fa3f5..789369503 100644
--- a/linux-user/unicore32/target_structs.h
+++ b/linux-user/unicore32/target_structs.h
@@ -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. */
diff --git a/linux-user/unicore32/target_syscall.h b/linux-user/unicore32/target_syscall.h
index 346b20770..385a97562 100644
--- a/linux-user/unicore32/target_syscall.h
+++ b/linux-user/unicore32/target_syscall.h
@@ -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__ */
diff --git a/linux-user/x86_64/target_signal.h b/linux-user/x86_64/target_signal.h
index 1e95f4a68..9baf7fbeb 100644
--- a/linux-user/x86_64/target_signal.h
+++ b/linux-user/x86_64/target_signal.h
@@ -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 */
diff --git a/linux-user/x86_64/target_structs.h b/linux-user/x86_64/target_structs.h
index b6e82a822..d93405614 100644
--- a/linux-user/x86_64/target_structs.h
+++ b/linux-user/x86_64/target_structs.h
@@ -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
diff --git a/linux-user/x86_64/target_syscall.h b/linux-user/x86_64/target_syscall.h
index 983fb23d9..feecd32d5 100644
--- a/linux-user/x86_64/target_syscall.h
+++ b/linux-user/x86_64/target_syscall.h
@@ -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 */
diff --git a/linux-user/x86_64/termbits.h b/linux-user/x86_64/termbits.h
index 387e74259..1c3445c6a 100644
--- a/linux-user/x86_64/termbits.h
+++ b/linux-user/x86_64/termbits.h
@@ -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
diff --git a/main-loop.c b/main-loop.c
index 6a7f8d30b..89a699419 100644
--- a/main-loop.c
+++ b/main-loop.c
@@ -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);
diff --git a/memory.c b/memory.c
index 0eb6895fe..f76f85df9 100644
--- 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);
}
diff --git a/memory_mapping.c b/memory_mapping.c
index e3e0d9517..2354b2b7f 100644
--- a/memory_mapping.c
+++ b/memory_mapping.c
@@ -13,6 +13,7 @@
#include "qemu/osdep.h"
#include "qapi/error.h"
+#include <glib.h>
#include "qemu-common.h"
#include "cpu.h"
diff --git a/migration/Makefile.objs b/migration/Makefile.objs
index 30ad94591..0cac6d707 100644
--- a/migration/Makefile.objs
+++ b/migration/Makefile.objs
@@ -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
diff --git a/migration/block.c b/migration/block.c
index ebc10e628..174331728 100644
--- a/migration/block.c
+++ b/migration/block.c
@@ -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);
}
diff --git a/migration/exec.c b/migration/exec.c
index 2af63cced..559420969 100644
--- a/migration/exec.c
+++ b/migration/exec.c
@@ -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.
@@ -20,53 +18,53 @@
#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);
}
diff --git a/migration/fd.c b/migration/fd.c
index 84a10fd68..3d788bb29 100644
--- a/migration/fd.c
+++ b/migration/fd.c
@@ -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.
@@ -17,57 +16,75 @@
#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);
}
diff --git a/migration/migration.c b/migration/migration.c
index 955d5ee38..4369e2782 100644
--- a/migration/migration.c
+++ b/migration/migration.c
@@ -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);
diff --git a/migration/postcopy-ram.c b/migration/postcopy-ram.c
index 9b0477835..fbd0064fc 100644
--- a/migration/postcopy-ram.c
+++ b/migration/postcopy-ram.c
@@ -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
index 000000000..7b8e78e99
--- /dev/null
+++ b/migration/qemu-file-buf.c
@@ -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
index 45c13f102..000000000
--- a/migration/qemu-file-channel.c
+++ /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);
-}
diff --git a/include/hw/dma/xlnx-zynq-devcfg.h b/migration/qemu-file-internal.h
index d40e5c8df..d95e8538e 100644
--- a/include/hw/dma/xlnx-zynq-devcfg.h
+++ b/migration/qemu-file-internal.h
@@ -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
@@ -24,39 +22,32 @@
* 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
index 000000000..f402e8f70
--- /dev/null
+++ b/migration/qemu-file-stdio.c
@@ -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
index 000000000..4474e18ff
--- /dev/null
+++ b/migration/qemu-file-unix.c
@@ -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;
+}
diff --git a/migration/qemu-file.c b/migration/qemu-file.c
index e9fae3115..6f4a1299b 100644
--- a/migration/qemu-file.c
+++ b/migration/qemu-file.c
@@ -30,31 +30,9 @@
#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));
}
}
diff --git a/migration/ram.c b/migration/ram.c
index a3d70c4c6..88fbffcce 100644
--- a/migration/ram.c
+++ b/migration/ram.c
@@ -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);
diff --git a/migration/rdma.c b/migration/rdma.c
index 5110ec828..f6a9992b3 100644
--- a/migration/rdma.c
+++ b/migration/rdma.c
@@ -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);
}
diff --git a/migration/savevm.c b/migration/savevm.c
index 33a2911ec..834664936 100644
--- a/migration/savevm.c
+++ b/migration/savevm.c
@@ -27,11 +27,9 @@
*/
#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
index 00de1fe12..000000000
--- a/migration/socket.c
+++ /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
index 000000000..e1fa7f8f1
--- /dev/null
+++ b/migration/tcp.c
@@ -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
index 12c053d15..000000000
--- a/migration/tls.c
+++ /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
index dfee75abf..000000000
--- a/migration/trace-events
+++ /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
index 000000000..d9aac36b9
--- /dev/null
+++ b/migration/unix.c
@@ -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);
+}
diff --git a/migration/vmstate.c b/migration/vmstate.c
index fc29acf74..bf3d5db30 100644
--- a/migration/vmstate.c
+++ b/migration/vmstate.c
@@ -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;
}
}
diff --git a/monitor.c b/monitor.c
index 5c003731e..d1c193013 100644
--- 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"
@@ -54,11 +52,15 @@
#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);
-}
diff --git a/nbd/client.c b/nbd/client.c
index a92f1e227..1a01b6c79 100644
--- a/nbd/client.c
+++ b/nbd/client.c
@@ -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) {
diff --git a/nbd/common.c b/nbd/common.c
index b583a4f4c..8ddb2dd2f 100644
--- a/nbd/common.c
+++ b/nbd/common.c
@@ -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;
diff --git a/nbd/nbd-internal.h b/nbd/nbd-internal.h
index 93a6ca854..379153561 100644
--- a/nbd/nbd-internal.h
+++ b/nbd/nbd-internal.h
@@ -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 {
diff --git a/nbd/server.c b/nbd/server.c
index 80fbb4da1..6f83bebcf 100644
--- a/nbd/server.c
+++ b/nbd/server.c
@@ -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);
}
diff --git a/net/checksum.c b/net/checksum.c
index 23323b076..d0fa424cc 100644
--- a/net/checksum.c
+++ b/net/checksum.c
@@ -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;
diff --git a/net/clients.h b/net/clients.h
index 5cae47973..d47530e82 100644
--- a/net/clients.h
+++ b/net/clients.h
@@ -27,39 +27,39 @@
#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 */
diff --git a/net/dump.c b/net/dump.c
index 89a149b5d..41f7673ef 100644
--- a/net/dump.c
+++ b/net/dump.c
@@ -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);
diff --git a/net/eth.c b/net/eth.c
index df81efb67..7e32d274c 100644
--- 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;
}
diff --git a/net/filter-mirror.c b/net/filter-mirror.c
index 35df37451..c0c4dc60b 100644
--- a/net/filter-mirror.c
+++ b/net/filter-mirror.c
@@ -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);
diff --git a/net/filter.c b/net/filter.c
index 888fe6dd9..8ac79f3b7 100644
--- a/net/filter.c
+++ b/net/filter.c
@@ -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",
diff --git a/net/hub.c b/net/hub.c
index 32d8cf5cd..6d90c6ee6 100644
--- 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:
diff --git a/net/l2tpv3.c b/net/l2tpv3.c
index 6745b7899..5c668f737 100644
--- a/net/l2tpv3.c
+++ b/net/l2tpv3.c
@@ -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;
diff --git a/net/net.c b/net/net.c
index d51cb2988..6b0b37501 100644
--- 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;
-}
diff --git a/net/netmap.c b/net/netmap.c
index 2d11a8f4b..6cc0db5ee 100644
--- a/net/netmap.c
+++ b/net/netmap.c
@@ -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;
diff --git a/net/slirp.c b/net/slirp.c
index b60893f9c..31630f005 100644
--- a/net/slirp.c
+++ b/net/slirp.c
@@ -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)) {
diff --git a/net/socket.c b/net/socket.c
index 3f98eefb3..9fa2cd8d5 100644
--- a/net/socket.c
+++ b/net/socket.c
@@ -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) {
diff --git a/net/tap-linux.h b/net/tap-linux.h
index 2f36d100f..1dc3a9f27 100644
--- a/net/tap-linux.h
+++ b/net/tap-linux.h
@@ -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 */
diff --git a/net/tap-win32.c b/net/tap-win32.c
index 662f9b63e..f1e142ace 100644
--- a/net/tap-win32.c
+++ b/net/tap-win32.c
@@ -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");
diff --git a/net/tap.c b/net/tap.c
index 6abb962ef..740e8a261 100644
--- 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;
}
diff --git a/net/tap_int.h b/net/tap_int.h
index ae6888f74..2378021c4 100644
--- a/net/tap_int.h
+++ b/net/tap_int.h
@@ -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
index 65c46a48f..000000000
--- a/net/trace-events
+++ /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"
diff --git a/net/vde.c b/net/vde.c
index e50e5d639..9427eaa16 100644
--- 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,
diff --git a/net/vhost-user.c b/net/vhost-user.c
index b0595f878..1b9e73a2d 100644
--- a/net/vhost-user.c
+++ b/net/vhost-user.c
@@ -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 6289f469b..572712ccf 100644
--- 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;
diff --git a/os-posix.c b/os-posix.c
index c6ddb7d83..107fde38b 100644
--- a/os-posix.c
+++ b/os-posix.c
@@ -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;
}
diff --git a/page_cache.c b/page_cache.c
index 5f8578736..cb8a69e96 100644
--- a/page_cache.c
+++ b/page_cache.c
@@ -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)
diff --git a/pc-bios/bios-256k.bin b/pc-bios/bios-256k.bin
index 57fb4d88b..e7a7e72e3 100644
--- a/pc-bios/bios-256k.bin
+++ b/pc-bios/bios-256k.bin
Binary files differ
diff --git a/pc-bios/bios.bin b/pc-bios/bios.bin
index 8a6869ff1..b0ae502f6 100644
--- a/pc-bios/bios.bin
+++ b/pc-bios/bios.bin
Binary files differ
diff --git a/pc-bios/efi-e1000.rom b/pc-bios/efi-e1000.rom
index 4e61f9b2d..4bc89a3d2 100644
--- a/pc-bios/efi-e1000.rom
+++ b/pc-bios/efi-e1000.rom
Binary files differ
diff --git a/pc-bios/efi-e1000e.rom b/pc-bios/efi-e1000e.rom
deleted file mode 100644
index 192a43729..000000000
--- a/pc-bios/efi-e1000e.rom
+++ /dev/null
Binary files differ
diff --git a/pc-bios/efi-eepro100.rom b/pc-bios/efi-eepro100.rom
index 66c52269c..85b7f9bc7 100644
--- a/pc-bios/efi-eepro100.rom
+++ b/pc-bios/efi-eepro100.rom
Binary files differ
diff --git a/pc-bios/efi-ne2k_pci.rom b/pc-bios/efi-ne2k_pci.rom
index 8c3e5fd6d..ebafd8452 100644
--- a/pc-bios/efi-ne2k_pci.rom
+++ b/pc-bios/efi-ne2k_pci.rom
Binary files differ
diff --git a/pc-bios/efi-pcnet.rom b/pc-bios/efi-pcnet.rom
index 802e225cb..6f1972375 100644
--- a/pc-bios/efi-pcnet.rom
+++ b/pc-bios/efi-pcnet.rom
Binary files differ
diff --git a/pc-bios/efi-rtl8139.rom b/pc-bios/efi-rtl8139.rom
index 8827181f3..086551b76 100644
--- a/pc-bios/efi-rtl8139.rom
+++ b/pc-bios/efi-rtl8139.rom
Binary files differ
diff --git a/pc-bios/efi-virtio.rom b/pc-bios/efi-virtio.rom
index 2fc049795..140c6806d 100644
--- a/pc-bios/efi-virtio.rom
+++ b/pc-bios/efi-virtio.rom
Binary files differ
diff --git a/pc-bios/efi-vmxnet3.rom b/pc-bios/efi-vmxnet3.rom
deleted file mode 100644
index 3d42635d1..000000000
--- a/pc-bios/efi-vmxnet3.rom
+++ /dev/null
Binary files differ
diff --git a/pc-bios/linuxboot_dma.bin b/pc-bios/linuxboot_dma.bin
deleted file mode 100644
index 238a195d3..000000000
--- a/pc-bios/linuxboot_dma.bin
+++ /dev/null
Binary files differ
diff --git a/pc-bios/openbios-ppc b/pc-bios/openbios-ppc
index d913fd007..ff980adb1 100644
--- a/pc-bios/openbios-ppc
+++ b/pc-bios/openbios-ppc
Binary files differ
diff --git a/pc-bios/openbios-sparc32 b/pc-bios/openbios-sparc32
index c8c6fcbe7..e744e898b 100644
--- a/pc-bios/openbios-sparc32
+++ b/pc-bios/openbios-sparc32
Binary files differ
diff --git a/pc-bios/openbios-sparc64 b/pc-bios/openbios-sparc64
index 73f03a04a..4d23be3ed 100644
--- a/pc-bios/openbios-sparc64
+++ b/pc-bios/openbios-sparc64
Binary files differ
diff --git a/pc-bios/optionrom/Makefile b/pc-bios/optionrom/Makefile
index afa48f1cf..ce4852a4d 100644
--- a/pc-bios/optionrom/Makefile
+++ b/pc-bios/optionrom/Makefile
@@ -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
index 9c8d25d50..000000000
--- a/pc-bios/optionrom/code16gcc.h
+++ /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
index cee2eda19..000000000
--- a/pc-bios/optionrom/flat.lds
+++ /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
index 754979773..000000000
--- a/pc-bios/optionrom/linuxboot_dma.c
+++ /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));
-}
diff --git a/pc-bios/s390-ccw.img b/pc-bios/s390-ccw.img
index 089f6ba5e..d3978ba05 100644
--- a/pc-bios/s390-ccw.img
+++ b/pc-bios/s390-ccw.img
Binary files differ
diff --git a/pc-bios/s390-ccw/Makefile b/pc-bios/s390-ccw/Makefile
index 0ab25388a..4208cb429 100644
--- a/pc-bios/s390-ccw/Makefile
+++ b/pc-bios/s390-ccw/Makefile
@@ -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
index 86abc56a9..000000000
--- a/pc-bios/s390-ccw/iplb.h
+++ /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 */
diff --git a/pc-bios/s390-ccw/main.c b/pc-bios/s390-ccw/main.c
index 345b84875..1c9e0791a 100644
--- a/pc-bios/s390-ccw/main.c
+++ b/pc-bios/s390-ccw/main.c
@@ -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 */
diff --git a/pc-bios/s390-ccw/s390-ccw.h b/pc-bios/s390-ccw/s390-ccw.h
index ded67bcbc..616d96738 100644
--- a/pc-bios/s390-ccw/s390-ccw.h
+++ b/pc-bios/s390-ccw/s390-ccw.h
@@ -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);
diff --git a/pc-bios/s390-ccw/start.S b/pc-bios/s390-ccw/start.S
index 43f9bd243..b6dd8c2fb 100644
--- a/pc-bios/s390-ccw/start.S
+++ b/pc-bios/s390-ccw/start.S
@@ -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 */
/*
diff --git a/pc-bios/s390-ccw/virtio-scsi.c b/pc-bios/s390-ccw/virtio-scsi.c
index d850a8dee..3bb48e917 100644
--- a/pc-bios/s390-ccw/virtio-scsi.c
+++ b/pc-bios/s390-ccw/virtio-scsi.c
@@ -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 */
diff --git a/pc-bios/s390-ccw/virtio.h b/pc-bios/s390-ccw/virtio.h
index eb35ea5fa..3c6e91510 100644
--- a/pc-bios/s390-ccw/virtio.h
+++ b/pc-bios/s390-ccw/virtio.h
@@ -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;
diff --git a/po/Makefile b/po/Makefile
index 7bab09dce..b271f79ba 100644
--- a/po/Makefile
+++ b/po/Makefile
@@ -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
index 50478616e..000000000
--- 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 "_Изглед"
diff --git a/qapi-schema.json b/qapi-schema.json
index 5658723b3..54634c473 100644
--- a/qapi-schema.json
+++ b/qapi-schema.json
@@ -382,17 +382,13 @@
#
# @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
@@ -484,13 +480,9 @@
# 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
##
@@ -502,8 +494,7 @@
'*expected-downtime': 'int',
'*downtime': 'int',
'*setup-time': 'int',
- '*cpu-throttle-percentage': 'int',
- '*error-desc': 'str'} }
+ '*x-cpu-throttle-percentage': 'int'} }
##
# @query-migrate
@@ -614,35 +605,18 @@
# 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
@@ -655,39 +629,21 @@
#
# @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
@@ -698,28 +654,13 @@
#
# @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
##
@@ -727,10 +668,8 @@
'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
#
@@ -2592,9 +2531,6 @@
#
# @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',
@@ -2611,8 +2547,7 @@
'*vhostfd': 'str',
'*vhostfds': 'str',
'*vhostforce': 'bool',
- '*queues': 'uint32',
- '*poll-us': 'uint32'} }
+ '*queues': 'uint32'} }
##
# @NetdevSocketOptions
@@ -2809,32 +2744,16 @@
'*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',
@@ -2869,28 +2788,23 @@
'*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
@@ -3011,14 +2925,11 @@
# @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:
@@ -4107,9 +4018,8 @@
## @ACPISlotType
#
# @DIMM: memory slot
-# @CPU: logical CPU slot (since 2.7)
#
-{ 'enum': 'ACPISlotType', 'data': [ 'DIMM', 'CPU' ] }
+{ 'enum': 'ACPISlotType', 'data': [ 'DIMM' ] }
## @ACPIOSTInfo
#
@@ -4234,20 +4144,6 @@
'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
@@ -4282,59 +4178,3 @@
# 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'] }
diff --git a/qapi/Makefile.objs b/qapi/Makefile.objs
index 7ea4aebb0..227897069 100644
--- a/qapi/Makefile.objs
+++ b/qapi/Makefile.objs
@@ -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
diff --git a/qapi/block-core.json b/qapi/block-core.json
index 5e2d7d78d..1d09079cc 100644
--- a/qapi/block-core.json
+++ b/qapi/block-core.json
@@ -85,11 +85,7 @@
{ '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'
} }
##
@@ -668,12 +664,10 @@
# @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:
@@ -719,8 +713,7 @@
#
# @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
#
@@ -873,9 +866,6 @@
##
# @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
@@ -913,8 +903,8 @@
# 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' } }
@@ -922,12 +912,9 @@
##
# @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
@@ -951,7 +938,7 @@
# 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',
@@ -1017,9 +1004,6 @@
# 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.
@@ -1071,7 +1055,7 @@
#
##
{ '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' } }
##
@@ -1124,24 +1108,6 @@
#
# 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
@@ -1188,11 +1154,14 @@
# 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',
@@ -1274,9 +1243,6 @@
#
# 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
@@ -1313,7 +1279,7 @@
# 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',
@@ -1346,21 +1312,6 @@
# 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
@@ -1427,9 +1378,12 @@
#
# @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',
@@ -1459,9 +1413,6 @@
# 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
@@ -1493,9 +1444,8 @@
# 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:
@@ -1506,9 +1456,7 @@
#
# 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.
@@ -1539,9 +1487,7 @@
# 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.
@@ -1567,9 +1513,7 @@
# 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
@@ -1589,9 +1533,7 @@
#
# 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
@@ -1617,9 +1559,7 @@
#
# 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
@@ -1692,16 +1632,15 @@
# 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
@@ -2022,8 +1961,7 @@
#
# @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
#
@@ -2094,63 +2032,6 @@
'*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
@@ -2167,8 +2048,20 @@
# @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)
#
@@ -2178,13 +2071,17 @@
##
{ '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': {
@@ -2197,7 +2094,7 @@
'file': 'BlockdevOptionsFile',
'ftp': 'BlockdevOptionsFile',
'ftps': 'BlockdevOptionsFile',
- 'gluster': 'BlockdevOptionsGluster',
+# TODO gluster: Wait for structured options
'host_cdrom': 'BlockdevOptionsFile',
'host_device':'BlockdevOptionsFile',
'http': 'BlockdevOptionsFile',
@@ -2507,8 +2404,7 @@
#
# @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
#
@@ -2539,8 +2435,7 @@
#
# @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
#
@@ -2563,8 +2458,7 @@
#
# 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
#
@@ -2584,8 +2478,7 @@
#
# @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
#
@@ -2663,35 +2556,3 @@
##
{ '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' } }
diff --git a/qapi/crypto.json b/qapi/crypto.json
index 34d258315..760d0c057 100644
--- a/qapi/crypto.json
+++ b/qapi/crypto.json
@@ -42,16 +42,12 @@
#
# @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']}
##
@@ -224,90 +220,3 @@
'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' } }
diff --git a/qapi/opts-visitor.c b/qapi/opts-visitor.c
index 1048bbc84..602f2609c 100644
--- a/qapi/opts-visitor.c
+++ b/qapi/opts-visitor.c
@@ -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
index 0bb821637..000000000
--- a/qapi/qapi-clone-visitor.c
+++ /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;
-}
diff --git a/qapi/qapi-dealloc-visitor.c b/qapi/qapi-dealloc-visitor.c
index e39457bc7..69221794e 100644
--- a/qapi/qapi-dealloc-visitor.c
+++ b/qapi/qapi-dealloc-visitor.c
@@ -19,18 +19,58 @@
#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;
}
diff --git a/qapi/qapi-visit-core.c b/qapi/qapi-visit-core.c
index 55f5876dc..fa680c999 100644
--- a/qapi/qapi-visit-core.c
+++ b/qapi/qapi-visit-core.c
@@ -20,94 +20,47 @@
#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;
- }
-}
diff --git a/qapi/qmp-dispatch.c b/qapi/qmp-dispatch.c
index 505eb418a..510a1aead 100644
--- a/qapi/qmp-dispatch.c
+++ b/qapi/qmp-dispatch.c
@@ -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);
diff --git a/qapi/qmp-input-visitor.c b/qapi/qmp-input-visitor.c
index 64dd392e6..7cd1b777a 100644
--- a/qapi/qmp-input-visitor.c
+++ b/qapi/qmp-input-visitor.c
@@ -25,27 +25,16 @@
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;
}
diff --git a/qapi/qmp-output-visitor.c b/qapi/qmp-output-visitor.c
index 9e3b67ce1..d44c67631 100644
--- a/qapi/qmp-output-visitor.c
+++ b/qapi/qmp-output-visitor.c
@@ -22,22 +22,22 @@
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;
}
diff --git a/qapi/qmp-registry.c b/qapi/qmp-registry.c
index 68b24c98b..4ebfbccd4 100644
--- a/qapi/qmp-registry.c
+++ b/qapi/qmp-registry.c
@@ -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;
diff --git a/qapi/string-input-visitor.c b/qapi/string-input-visitor.c
index 8dfa56125..5ea2d77b5 100644
--- a/qapi/string-input-visitor.c
+++ b/qapi/string-input-visitor.c
@@ -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;
}
diff --git a/qapi/string-output-visitor.c b/qapi/string-output-visitor.c
index 94ac8211d..c2e5c5b92 100644
--- a/qapi/string-output-visitor.c
+++ b/qapi/string-output-visitor.c
@@ -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;
}
diff --git a/qapi/trace.json b/qapi/trace.json
index e87214677..01b0a52a7 100644
--- a/qapi/trace.json
+++ b/qapi/trace.json
@@ -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.
@@ -29,15 +29,11 @@
#
# @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:
@@ -45,23 +41,13 @@
# 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'] }
##
@@ -72,19 +58,8 @@
# @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'} }
diff --git a/qemu-bridge-helper.c b/qemu-bridge-helper.c
index 5396fbfbb..830fb9e26 100644
--- a/qemu-bridge-helper.c
+++ b/qemu-bridge-helper.c
@@ -15,6 +15,7 @@
#include "qemu/osdep.h"
+#include <glib.h>
#include <sys/ioctl.h>
#include <sys/socket.h>
diff --git a/qemu-char.c b/qemu-char.c
index 5f82ebb77..b597ee19c 100644
--- a/qemu-char.c
+++ b/qemu-char.c
@@ -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,
diff --git a/qemu-doc.texi b/qemu-doc.texi
index f37fd3130..79141d358 100644
--- a/qemu-doc.texi
+++ b/qemu-doc.texi
@@ -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),
diff --git a/qemu-img-cmds.hx b/qemu-img-cmds.hx
index 7e95b2da7..e7cded6e2 100644
--- a/qemu-img-cmds.hx
+++ b/qemu-img-cmds.hx
@@ -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
diff --git a/qemu-img.c b/qemu-img.c
index f204d0413..46f2a6def 100644
--- a/qemu-img.c
+++ b/qemu-img.c
@@ -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"
@@ -40,11 +38,10 @@
#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 */
diff --git a/qemu-img.texi b/qemu-img.texi
index 449a19c71..afaebdd40 100644
--- a/qemu-img.texi
+++ b/qemu-img.texi
@@ -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
diff --git a/qemu-io-cmds.c b/qemu-io-cmds.c
index 25954f563..e34f77711 100644
--- a/qemu-io-cmds.c
+++ b/qemu-io-cmds.c
@@ -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);
diff --git a/qemu-io.c b/qemu-io.c
index db129eac5..0598251e7 100644
--- 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);
diff --git a/qemu-nbd.c b/qemu-nbd.c
index e3571c202..6dea6d69d 100644
--- a/qemu-nbd.c
+++ b/qemu-nbd.c
@@ -26,15 +26,12 @@
#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");
diff --git a/qemu-nbd.texi b/qemu-nbd.texi
index 91ebf04b5..9f2334345 100644
--- a/qemu-nbd.texi
+++ b/qemu-nbd.texi
@@ -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
index 693ab5a3e..000000000
--- a/qemu-option-trace.texi
+++ /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
diff --git a/qemu-options.h b/qemu-options.h
index b4ee63cd6..89a009ee9 100644
--- a/qemu-options.h
+++ b/qemu-options.h
@@ -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
diff --git a/qemu-options.hx b/qemu-options.hx
index a71aaf8ea..6106520c5 100644
--- a/qemu-options.hx
+++ b/qemu-options.hx
@@ -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
diff --git a/qemu-timer.c b/qemu-timer.c
index 9299cdc5f..a8636cb3b 100644
--- a/qemu-timer.c
+++ b/qemu-timer.c
@@ -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) {
diff --git a/qga/channel-posix.c b/qga/channel-posix.c
index bb65d8ba1..63458c663 100644
--- a/qga/channel-posix.c
+++ b/qga/channel-posix.c
@@ -1,4 +1,5 @@
#include "qemu/osdep.h"
+#include <glib.h>
#include <termios.h>
#include "qapi/error.h"
#include "qemu/sockets.h"
diff --git a/qga/channel-win32.c b/qga/channel-win32.c
index 21f9deedf..68168d14a 100644
--- a/qga/channel-win32.c
+++ b/qga/channel-win32.c
@@ -1,4 +1,5 @@
#include "qemu/osdep.h"
+#include <glib.h>
#include <windows.h>
#include <io.h>
#include "qga/guest-agent-core.h"
diff --git a/qga/channel.h b/qga/channel.h
index ae8cf0f7e..3704ea9c8 100644
--- a/qga/channel.h
+++ b/qga/channel.h
@@ -12,6 +12,7 @@
#ifndef QGA_CHANNEL_H
#define QGA_CHANNEL_H
+#include <glib.h>
typedef struct GAChannel GAChannel;
diff --git a/qga/commands-posix.c b/qga/commands-posix.c
index ea37c097c..2ae37255d 100644
--- a/qga/commands-posix.c
+++ b/qga/commands-posix.c
@@ -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;
diff --git a/qga/commands-win32.c b/qga/commands-win32.c
index 9c9be1211..d76327f5a 100644
--- a/qga/commands-win32.c
+++ b/qga/commands-win32.c
@@ -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)
diff --git a/qga/commands.c b/qga/commands.c
index 50fd26a81..31444643e 100644
--- a/qga/commands.c
+++ b/qga/commands.c
@@ -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"
diff --git a/qga/guest-agent-command-state.c b/qga/guest-agent-command-state.c
index 4de229cd7..20b9b2222 100644
--- a/qga/guest-agent-command-state.c
+++ b/qga/guest-agent-command-state.c
@@ -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 {
diff --git a/qga/main.c b/qga/main.c
index 4c3b2c772..c55278210 100644
--- a/qga/main.c
+++ b/qga/main.c
@@ -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
diff --git a/qga/service-win32.c b/qga/service-win32.c
index fd434e3f4..72437587b 100644
--- a/qga/service-win32.c
+++ b/qga/service-win32.c
@@ -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"
diff --git a/qga/service-win32.h b/qga/service-win32.h
index 89e99dfed..3b9e87024 100644
--- a/qga/service-win32.h
+++ b/qga/service-win32.h
@@ -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>
diff --git a/qga/vss-win32/install.cpp b/qga/vss-win32/install.cpp
index f4160a3a8..cd9cdb4a2 100644
--- a/qga/vss-win32/install.cpp
+++ b/qga/vss-win32/install.cpp
@@ -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>
diff --git a/qga/vss-win32/provider.cpp b/qga/vss-win32/provider.cpp
index ef9466909..d977393e3 100644
--- a/qga/vss-win32/provider.cpp
+++ b/qga/vss-win32/provider.cpp
@@ -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)
diff --git a/qga/vss-win32/requester.cpp b/qga/vss-win32/requester.cpp
index 0cd2f0ee7..889052ded 100644
--- a/qga/vss-win32/requester.cpp
+++ b/qga/vss-win32/requester.cpp
@@ -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
diff --git a/qga/vss-win32/vss-common.h b/qga/vss-win32/vss-common.h
index c81a8564b..91dae0c38 100644
--- a/qga/vss-win32/vss-common.h
+++ b/qga/vss-win32/vss-common.h
@@ -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
diff --git a/migration/qjson.c b/qjson.c
index f34590491..b65ca6ee5 100644
--- a/migration/qjson.c
+++ b/qjson.c
@@ -1,5 +1,5 @@
/*
- * A simple JSON writer
+ * QEMU JSON writer
*
* Copyright Alexander Graf
*
@@ -11,27 +11,21 @@
*
*/
-/*
- * 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)
diff --git a/qmp-commands.hx b/qmp-commands.hx
index 6866264e6..de896a5a3 100644
--- a/qmp-commands.hx
+++ b/qmp-commands.hx
@@ -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 b6d531ebe..9d0953bc2 100644
--- 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);
}
diff --git a/qobject/json-lexer.c b/qobject/json-lexer.c
index af4a75e05..496374d9a 100644
--- a/qobject/json-lexer.c
+++ b/qobject/json-lexer.c
@@ -18,20 +18,11 @@
#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] = {
diff --git a/qobject/json-parser.c b/qobject/json-parser.c
index c18e48ab9..67ed72731 100644
--- a/qobject/json-parser.c
+++ b/qobject/json-parser.c
@@ -14,7 +14,12 @@
#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"
diff --git a/qobject/qdict.c b/qobject/qdict.c
index 60f158c3b..a1285361c 100644
--- a/qobject/qdict.c
+++ b/qobject/qdict.c
@@ -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;
}
diff --git a/qobject/qjson.c b/qobject/qjson.c
index 9a0de8907..ef160d211 100644
--- a/qobject/qjson.c
+++ b/qobject/qjson.c
@@ -16,7 +16,11 @@
#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
diff --git a/qobject/qlist.c b/qobject/qlist.c
index 86b60cb88..1ec74de2b 100644
--- a/qobject/qlist.c
+++ b/qobject/qlist.c
@@ -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)
diff --git a/qobject/qobject.c b/qobject/qobject.c
index fe4fa1098..cd41fb940 100644
--- a/qobject/qobject.c
+++ b/qobject/qobject.c
@@ -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 */
diff --git a/qom/cpu.c b/qom/cpu.c
index 255324790..c9007d3d0 100644
--- 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)
diff --git a/qom/object.c b/qom/object.c
index 8166b7dac..8e6e68dff 100644
--- a/qom/object.c
+++ b/qom/object.c
@@ -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);
diff --git a/qom/object_interfaces.c b/qom/object_interfaces.c
index bf598468a..393189024 100644
--- a/qom/object_interfaces.c
+++ b/qom/object_interfaces.c
@@ -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;
}
diff --git a/qom/qom-qobject.c b/qom/qom-qobject.c
index c225abcba..e6b17c1f1 100644
--- a/qom/qom-qobject.c
+++ b/qom/qom-qobject.c
@@ -21,11 +21,11 @@
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
index 97db35720..000000000
--- a/qom/trace-events
+++ /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 da4826c69..87575bc0b 100644
--- 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"
diff --git a/replay/replay-char.c b/replay/replay-char.c
index edf46ab9d..23b692297 100755
--- a/replay/replay-char.c
+++ b/replay/replay-char.c
@@ -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"
diff --git a/replay/replay-input.c b/replay/replay-input.c
index bd93554d8..06babe0ec 100644
--- a/replay/replay-input.c
+++ b/replay/replay-input.c
@@ -16,7 +16,35 @@
#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);
}
diff --git a/roms/Makefile b/roms/Makefile
index 88b3709d4..7bd125273 100644
--- a/roms/Makefile
+++ b/roms/Makefile
@@ -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
diff --git a/roms/config.seabios-128k b/roms/config.seabios-128k
index 93203af0d..0a9da77a5 100644
--- a/roms/config.seabios-128k
+++ b/roms/config.seabios-128k
@@ -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
diff --git a/roms/ipxe/src/Makefile b/roms/ipxe/src/Makefile
index 582ffe81c..2a9cc9e8f 100644
--- a/roms/ipxe/src/Makefile
+++ b/roms/ipxe/src/Makefile
@@ -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
index 151b33186..000000000
--- a/roms/ipxe/src/Makefile.efi
+++ /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) $<
diff --git a/roms/ipxe/src/Makefile.housekeeping b/roms/ipxe/src/Makefile.housekeeping
index ceff81410..03800c8ef 100644
--- a/roms/ipxe/src/Makefile.housekeeping
+++ b/roms/ipxe/src/Makefile.housekeeping
@@ -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
index 3cee5f3ac..000000000
--- a/roms/ipxe/src/arch/arm/Makefile
+++ /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
index f04be425b..000000000
--- a/roms/ipxe/src/arch/arm/Makefile.efi
+++ /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
index 1ef571fc1..000000000
--- a/roms/ipxe/src/arch/arm/core/arm_io.c
+++ /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
index 4506711ad..000000000
--- a/roms/ipxe/src/arch/arm/include/bits/endian.h
+++ /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
index 65f7f719b..000000000
--- a/roms/ipxe/src/arch/arm/include/bits/errfile.h
+++ /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
index f0e0c8793..000000000
--- a/roms/ipxe/src/arch/arm/include/bits/hyperv.h
+++ /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
index 90f6455ec..000000000
--- a/roms/ipxe/src/arch/arm/include/bits/io.h
+++ /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
index ae953c450..000000000
--- a/roms/ipxe/src/arch/arm/include/bits/iomap.h
+++ /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
index e30a7146b..000000000
--- a/roms/ipxe/src/arch/arm/include/bits/nap.h
+++ /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
index fba0eb979..000000000
--- a/roms/ipxe/src/arch/arm/include/bits/pci_io.h
+++ /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
index 6f85975f7..000000000
--- a/roms/ipxe/src/arch/arm/include/bits/uart.h
+++ /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
index 27970d7b2..000000000
--- a/roms/ipxe/src/arch/arm/include/bits/umalloc.h
+++ /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
index 34f647903..000000000
--- a/roms/ipxe/src/arch/arm/include/bits/xen.h
+++ /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
index f8765af75..000000000
--- a/roms/ipxe/src/arch/arm/include/ipxe/arm_io.h
+++ /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
index dcbdd3e20..000000000
--- a/roms/ipxe/src/arch/arm/include/ipxe/efi/efiarm_nap.h
+++ /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
index 9ed638e9a..000000000
--- a/roms/ipxe/src/arch/arm/interface/efi/efiarm_nap.c
+++ /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
index 3a7c09230..000000000
--- a/roms/ipxe/src/arch/arm32/Makefile
+++ /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
index a06354f1d..000000000
--- a/roms/ipxe/src/arch/arm32/Makefile.efi
+++ /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
index 839bead18..000000000
--- a/roms/ipxe/src/arch/arm32/core/arm32_bigint.c
+++ /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
index 7e7b0fe58..000000000
--- a/roms/ipxe/src/arch/arm32/core/setjmp.S
+++ /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
index 103c6c489..000000000
--- a/roms/ipxe/src/arch/arm32/include/bits/bigint.h
+++ /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
index 9a5fe14c2..000000000
--- a/roms/ipxe/src/arch/arm32/include/bits/bitops.h
+++ /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
index 1fc884bd8..000000000
--- a/roms/ipxe/src/arch/arm32/include/bits/byteswap.h
+++ /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
index e420cf922..000000000
--- a/roms/ipxe/src/arch/arm32/include/bits/compiler.h
+++ /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
index 2b15d1604..000000000
--- a/roms/ipxe/src/arch/arm32/include/bits/profile.h
+++ /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
index fe1f9946a..000000000
--- a/roms/ipxe/src/arch/arm32/include/bits/stdint.h
+++ /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
index 5b1c1505d..000000000
--- a/roms/ipxe/src/arch/arm32/include/bits/string.h
+++ /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
index adbd5f4b4..000000000
--- a/roms/ipxe/src/arch/arm32/include/bits/strings.h
+++ /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
index fc3c5b3ff..000000000
--- a/roms/ipxe/src/arch/arm32/include/bits/tcpip.h
+++ /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
index f9baab4fa..000000000
--- a/roms/ipxe/src/arch/arm32/include/efi/ipxe/dhcp_arch.h
+++ /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
index cd152eedd..000000000
--- a/roms/ipxe/src/arch/arm32/include/gdbmach.h
+++ /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
index bb48b75ab..000000000
--- a/roms/ipxe/src/arch/arm32/include/limits.h
+++ /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
index 4828b47a2..000000000
--- a/roms/ipxe/src/arch/arm32/include/setjmp.h
+++ /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
index 910be4b78..000000000
--- a/roms/ipxe/src/arch/arm32/libgcc/lldivmod.S
+++ /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
index cc16e2615..000000000
--- a/roms/ipxe/src/arch/arm32/libgcc/llshift.S
+++ /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
index d121871f7..000000000
--- a/roms/ipxe/src/arch/arm64/Makefile
+++ /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
index 998a64d03..000000000
--- a/roms/ipxe/src/arch/arm64/Makefile.efi
+++ /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
index bc4ee9a00..000000000
--- a/roms/ipxe/src/arch/arm64/core/arm64_bigint.c
+++ /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
index 28a2b73bc..000000000
--- a/roms/ipxe/src/arch/arm64/core/arm64_string.c
+++ /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
index 0ef04ea42..000000000
--- a/roms/ipxe/src/arch/arm64/core/arm64_tcpip.c
+++ /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
index fa47aa0af..000000000
--- a/roms/ipxe/src/arch/arm64/core/setjmp.S
+++ /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
index 79983b410..000000000
--- a/roms/ipxe/src/arch/arm64/include/bits/bigint.h
+++ /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
index 4350f622a..000000000
--- a/roms/ipxe/src/arch/arm64/include/bits/bitops.h
+++ /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
index 169d6c20e..000000000
--- a/roms/ipxe/src/arch/arm64/include/bits/byteswap.h
+++ /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
index 3b129c2fd..000000000
--- a/roms/ipxe/src/arch/arm64/include/bits/compiler.h
+++ /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
index 62ffa3772..000000000
--- a/roms/ipxe/src/arch/arm64/include/bits/profile.h
+++ /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
index 9eb72e9c4..000000000
--- a/roms/ipxe/src/arch/arm64/include/bits/stdint.h
+++ /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
index c05fbe346..000000000
--- a/roms/ipxe/src/arch/arm64/include/bits/string.h
+++ /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
index d5340f484..000000000
--- a/roms/ipxe/src/arch/arm64/include/bits/strings.h
+++ /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
index 68686534e..000000000
--- a/roms/ipxe/src/arch/arm64/include/bits/tcpip.h
+++ /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
index 48a36d052..000000000
--- a/roms/ipxe/src/arch/arm64/include/efi/ipxe/dhcp_arch.h
+++ /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
index cd152eedd..000000000
--- a/roms/ipxe/src/arch/arm64/include/gdbmach.h
+++ /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
index 8cf87b471..000000000
--- a/roms/ipxe/src/arch/arm64/include/limits.h
+++ /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
index 85a7a9cad..000000000
--- a/roms/ipxe/src/arch/arm64/include/setjmp.h
+++ /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 */
diff --git a/roms/ipxe/src/arch/i386/Makefile b/roms/ipxe/src/arch/i386/Makefile
index fe3adc9ce..99f875314 100644
--- a/roms/ipxe/src/arch/i386/Makefile
+++ b/roms/ipxe/src/arch/i386/Makefile
@@ -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
#
diff --git a/roms/ipxe/src/arch/i386/Makefile.efi b/roms/ipxe/src/arch/i386/Makefile.efi
index 37ede65ac..aa809eb5d 100644
--- a/roms/ipxe/src/arch/i386/Makefile.efi
+++ b/roms/ipxe/src/arch/i386/Makefile.efi
@@ -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
diff --git a/roms/ipxe/src/arch/i386/Makefile.pcbios b/roms/ipxe/src/arch/i386/Makefile.pcbios
index dfb8db0a0..ff823737d 100644
--- a/roms/ipxe/src/arch/i386/Makefile.pcbios
+++ b/roms/ipxe/src/arch/i386/Makefile.pcbios
@@ -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 $@
diff --git a/roms/ipxe/src/arch/x86/core/basemem_packet.c b/roms/ipxe/src/arch/i386/core/basemem_packet.c
index 9f5fbf330..9f5fbf330 100644
--- a/roms/ipxe/src/arch/x86/core/basemem_packet.c
+++ b/roms/ipxe/src/arch/i386/core/basemem_packet.c
diff --git a/roms/ipxe/src/arch/x86/core/cachedhcp.c b/roms/ipxe/src/arch/i386/core/cachedhcp.c
index ff35b9256..a5c624035 100644
--- a/roms/ipxe/src/arch/x86/core/cachedhcp.c
+++ b/roms/ipxe/src/arch/i386/core/cachedhcp.c
@@ -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;
diff --git a/roms/ipxe/src/arch/x86/core/dumpregs.c b/roms/ipxe/src/arch/i386/core/dumpregs.c
index 37d62a7b6..82dc21847 100644
--- a/roms/ipxe/src/arch/x86/core/dumpregs.c
+++ b/roms/ipxe/src/arch/i386/core/dumpregs.c
@@ -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"
diff --git a/roms/ipxe/src/arch/i386/core/gdbidt.S b/roms/ipxe/src/arch/i386/core/gdbidt.S
index 666ecce3c..a1e309d7c 100644
--- a/roms/ipxe/src/arch/i386/core/gdbidt.S
+++ b/roms/ipxe/src/arch/i386/core/gdbidt.S
@@ -15,29 +15,41 @@
/* 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
index 000000000..d92a4ac08
--- /dev/null
+++ b/roms/ipxe/src/arch/i386/core/gdbmach.c
@@ -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] );
+ }
+}
diff --git a/roms/ipxe/src/arch/x86/core/patch_cf.S b/roms/ipxe/src/arch/i386/core/patch_cf.S
index 4365563fe..4365563fe 100644
--- a/roms/ipxe/src/arch/x86/core/patch_cf.S
+++ b/roms/ipxe/src/arch/i386/core/patch_cf.S
diff --git a/roms/ipxe/src/arch/x86/core/pci_autoboot.c b/roms/ipxe/src/arch/i386/core/pci_autoboot.c
index 337598091..337598091 100644
--- a/roms/ipxe/src/arch/x86/core/pci_autoboot.c
+++ b/roms/ipxe/src/arch/i386/core/pci_autoboot.c
diff --git a/roms/ipxe/src/arch/x86/core/rdtsc_timer.c b/roms/ipxe/src/arch/i386/core/rdtsc_timer.c
index e720a239c..e720a239c 100644
--- a/roms/ipxe/src/arch/x86/core/rdtsc_timer.c
+++ b/roms/ipxe/src/arch/i386/core/rdtsc_timer.c
diff --git a/roms/ipxe/src/arch/x86/core/relocate.c b/roms/ipxe/src/arch/i386/core/relocate.c
index 765d46560..54ad387e4 100644
--- a/roms/ipxe/src/arch/x86/core/relocate.c
+++ b/roms/ipxe/src/arch/i386/core/relocate.c
@@ -10,6 +10,14 @@
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 */
diff --git a/roms/ipxe/src/arch/x86/core/runtime.c b/roms/ipxe/src/arch/i386/core/runtime.c
index d160fee04..d160fee04 100644
--- a/roms/ipxe/src/arch/x86/core/runtime.c
+++ b/roms/ipxe/src/arch/i386/core/runtime.c
diff --git a/roms/ipxe/src/arch/x86/core/stack.S b/roms/ipxe/src/arch/i386/core/stack.S
index 995c397ca..98f1cd9b9 100644
--- a/roms/ipxe/src/arch/x86/core/stack.S
+++ b/roms/ipxe/src/arch/i386/core/stack.S
@@ -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/x86/core/stack16.S b/roms/ipxe/src/arch/i386/core/stack16.S
index 4bc6f081a..4bc6f081a 100644
--- a/roms/ipxe/src/arch/x86/core/stack16.S
+++ b/roms/ipxe/src/arch/i386/core/stack16.S
diff --git a/roms/ipxe/src/arch/x86/core/video_subr.c b/roms/ipxe/src/arch/i386/core/video_subr.c
index 3f701bd96..3f701bd96 100644
--- a/roms/ipxe/src/arch/x86/core/video_subr.c
+++ b/roms/ipxe/src/arch/i386/core/video_subr.c
diff --git a/roms/ipxe/src/arch/i386/core/virtaddr.S b/roms/ipxe/src/arch/i386/core/virtaddr.S
new file mode 100644
index 000000000..425591570
--- /dev/null
+++ b/roms/ipxe/src/arch/i386/core/virtaddr.S
@@ -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
diff --git a/roms/ipxe/src/arch/x86/drivers/net/undi.c b/roms/ipxe/src/arch/i386/drivers/net/undi.c
index 9820cf629..9820cf629 100644
--- a/roms/ipxe/src/arch/x86/drivers/net/undi.c
+++ b/roms/ipxe/src/arch/i386/drivers/net/undi.c
diff --git a/roms/ipxe/src/arch/x86/drivers/net/undiisr.S b/roms/ipxe/src/arch/i386/drivers/net/undiisr.S
index b27effe1d..b27effe1d 100644
--- a/roms/ipxe/src/arch/x86/drivers/net/undiisr.S
+++ b/roms/ipxe/src/arch/i386/drivers/net/undiisr.S
diff --git a/roms/ipxe/src/arch/x86/drivers/net/undiload.c b/roms/ipxe/src/arch/i386/drivers/net/undiload.c
index 7160ee384..7160ee384 100644
--- a/roms/ipxe/src/arch/x86/drivers/net/undiload.c
+++ b/roms/ipxe/src/arch/i386/drivers/net/undiload.c
diff --git a/roms/ipxe/src/arch/x86/drivers/net/undinet.c b/roms/ipxe/src/arch/i386/drivers/net/undinet.c
index 091ef9254..6450665ff 100644
--- a/roms/ipxe/src/arch/x86/drivers/net/undinet.c
+++ b/roms/ipxe/src/arch/i386/drivers/net/undinet.c
@@ -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 },
};
/**
diff --git a/roms/ipxe/src/arch/x86/drivers/net/undionly.c b/roms/ipxe/src/arch/i386/drivers/net/undionly.c
index 70dbe4bfd..70dbe4bfd 100644
--- a/roms/ipxe/src/arch/x86/drivers/net/undionly.c
+++ b/roms/ipxe/src/arch/i386/drivers/net/undionly.c
diff --git a/roms/ipxe/src/arch/x86/drivers/net/undipreload.c b/roms/ipxe/src/arch/i386/drivers/net/undipreload.c
index fca771843..fca771843 100644
--- a/roms/ipxe/src/arch/x86/drivers/net/undipreload.c
+++ b/roms/ipxe/src/arch/i386/drivers/net/undipreload.c
diff --git a/roms/ipxe/src/arch/x86/drivers/net/undirom.c b/roms/ipxe/src/arch/i386/drivers/net/undirom.c
index b54c6170f..b54c6170f 100644
--- a/roms/ipxe/src/arch/x86/drivers/net/undirom.c
+++ b/roms/ipxe/src/arch/i386/drivers/net/undirom.c
diff --git a/roms/ipxe/src/arch/x86/interface/pcbios/basemem.c b/roms/ipxe/src/arch/i386/firmware/pcbios/basemem.c
index 6a46081aa..6a46081aa 100644
--- a/roms/ipxe/src/arch/x86/interface/pcbios/basemem.c
+++ b/roms/ipxe/src/arch/i386/firmware/pcbios/basemem.c
diff --git a/roms/ipxe/src/arch/x86/interface/pcbios/bios_console.c b/roms/ipxe/src/arch/i386/firmware/pcbios/bios_console.c
index c081a41e6..63413cdc1 100644
--- a/roms/ipxe/src/arch/x86/interface/pcbios/bios_console.c
+++ b/roms/ipxe/src/arch/i386/firmware/pcbios/bios_console.c
@@ -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,
-};
diff --git a/roms/ipxe/src/arch/x86/interface/pcbios/e820mangler.S b/roms/ipxe/src/arch/i386/firmware/pcbios/e820mangler.S
index d5d97b482..d5d97b482 100644
--- a/roms/ipxe/src/arch/x86/interface/pcbios/e820mangler.S
+++ b/roms/ipxe/src/arch/i386/firmware/pcbios/e820mangler.S
diff --git a/roms/ipxe/src/arch/x86/interface/pcbios/fakee820.c b/roms/ipxe/src/arch/i386/firmware/pcbios/fakee820.c
index 8b083c4f0..15f4d772f 100644
--- a/roms/ipxe/src/arch/x86/interface/pcbios/fakee820.c
+++ b/roms/ipxe/src/arch/i386/firmware/pcbios/fakee820.c
@@ -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 );
}
diff --git a/roms/ipxe/src/arch/x86/interface/pcbios/hidemem.c b/roms/ipxe/src/arch/i386/firmware/pcbios/hidemem.c
index a3728123c..253c601ff 100644
--- a/roms/ipxe/src/arch/x86/interface/pcbios/hidemem.c
+++ b/roms/ipxe/src/arch/i386/firmware/pcbios/hidemem.c
@@ -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,
diff --git a/roms/ipxe/src/arch/x86/interface/pcbios/memmap.c b/roms/ipxe/src/arch/i386/firmware/pcbios/memmap.c
index daae382b8..bcacecd6a 100644
--- a/roms/ipxe/src/arch/x86/interface/pcbios/memmap.c
+++ b/roms/ipxe/src/arch/i386/firmware/pcbios/memmap.c
@@ -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;
}
diff --git a/roms/ipxe/src/arch/x86/interface/pcbios/pnpbios.c b/roms/ipxe/src/arch/i386/firmware/pcbios/pnpbios.c
index 20ec35d75..20ec35d75 100644
--- a/roms/ipxe/src/arch/x86/interface/pcbios/pnpbios.c
+++ b/roms/ipxe/src/arch/i386/firmware/pcbios/pnpbios.c
diff --git a/roms/ipxe/src/arch/x86/hci/commands/pxe_cmd.c b/roms/ipxe/src/arch/i386/hci/commands/pxe_cmd.c
index 473b97f97..473b97f97 100644
--- a/roms/ipxe/src/arch/x86/hci/commands/pxe_cmd.c
+++ b/roms/ipxe/src/arch/i386/hci/commands/pxe_cmd.c
diff --git a/roms/ipxe/src/arch/x86/image/bootsector.c b/roms/ipxe/src/arch/i386/image/bootsector.c
index 67dad04f8..dba87613c 100644
--- a/roms/ipxe/src/arch/x86/image/bootsector.c
+++ b/roms/ipxe/src/arch/i386/image/bootsector.c
@@ -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;
diff --git a/roms/ipxe/src/arch/x86/image/bzimage.c b/roms/ipxe/src/arch/i386/image/bzimage.c
index d9b5ddc07..a64206cd3 100644
--- a/roms/ipxe/src/arch/x86/image/bzimage.c
+++ b/roms/ipxe/src/arch/i386/image/bzimage.c
@@ -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.
diff --git a/roms/ipxe/src/arch/x86/image/com32.c b/roms/ipxe/src/arch/i386/image/com32.c
index 016652877..c12ffb684 100644
--- a/roms/ipxe/src/arch/x86/image/com32.c
+++ b/roms/ipxe/src/arch/i386/image/com32.c
@@ -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 );
}
diff --git a/roms/ipxe/src/arch/x86/image/comboot.c b/roms/ipxe/src/arch/i386/image/comboot.c
index 9a847f0ff..1ec02331d 100644
--- a/roms/ipxe/src/arch/x86/image/comboot.c
+++ b/roms/ipxe/src/arch/i386/image/comboot.c
@@ -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 );
}
diff --git a/roms/ipxe/src/arch/x86/image/elfboot.c b/roms/ipxe/src/arch/i386/image/elfboot.c
index dc3568929..dc3568929 100644
--- a/roms/ipxe/src/arch/x86/image/elfboot.c
+++ b/roms/ipxe/src/arch/i386/image/elfboot.c
diff --git a/roms/ipxe/src/arch/x86/image/initrd.c b/roms/ipxe/src/arch/i386/image/initrd.c
index 80c197417..80c197417 100644
--- a/roms/ipxe/src/arch/x86/image/initrd.c
+++ b/roms/ipxe/src/arch/i386/image/initrd.c
diff --git a/roms/ipxe/src/arch/x86/image/multiboot.c b/roms/ipxe/src/arch/i386/image/multiboot.c
index 0c85df708..0c85df708 100644
--- a/roms/ipxe/src/arch/x86/image/multiboot.c
+++ b/roms/ipxe/src/arch/i386/image/multiboot.c
diff --git a/roms/ipxe/src/arch/x86/image/nbi.c b/roms/ipxe/src/arch/i386/image/nbi.c
index b691bee20..99046144d 100644
--- a/roms/ipxe/src/arch/x86/image/nbi.c
+++ b/roms/ipxe/src/arch/i386/image/nbi.c
@@ -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 );
diff --git a/roms/ipxe/src/arch/x86/image/pxe_image.c b/roms/ipxe/src/arch/i386/image/pxe_image.c
index 297a618b8..5b0f6eb89 100644
--- a/roms/ipxe/src/arch/x86/image/pxe_image.c
+++ b/roms/ipxe/src/arch/i386/image/pxe_image.c
@@ -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;
diff --git a/roms/ipxe/src/arch/x86/image/sdi.c b/roms/ipxe/src/arch/i386/image/sdi.c
index fa2d0b73f..fa2d0b73f 100644
--- a/roms/ipxe/src/arch/x86/image/sdi.c
+++ b/roms/ipxe/src/arch/i386/image/sdi.c
diff --git a/roms/ipxe/src/arch/x86/include/basemem.h b/roms/ipxe/src/arch/i386/include/basemem.h
index 01c2ea917..01c2ea917 100644
--- a/roms/ipxe/src/arch/x86/include/basemem.h
+++ b/roms/ipxe/src/arch/i386/include/basemem.h
diff --git a/roms/ipxe/src/arch/x86/include/basemem_packet.h b/roms/ipxe/src/arch/i386/include/basemem_packet.h
index def6dee31..def6dee31 100644
--- a/roms/ipxe/src/arch/x86/include/basemem_packet.h
+++ b/roms/ipxe/src/arch/i386/include/basemem_packet.h
diff --git a/roms/ipxe/src/arch/x86/include/bios.h b/roms/ipxe/src/arch/i386/include/bios.h
index 988bbc62b..988bbc62b 100644
--- a/roms/ipxe/src/arch/x86/include/bios.h
+++ b/roms/ipxe/src/arch/i386/include/bios.h
diff --git a/roms/ipxe/src/arch/x86/include/bios_disks.h b/roms/ipxe/src/arch/i386/include/bios_disks.h
index 0dd7c4ebb..0dd7c4ebb 100644
--- a/roms/ipxe/src/arch/x86/include/bios_disks.h
+++ b/roms/ipxe/src/arch/i386/include/bios_disks.h
diff --git a/roms/ipxe/src/arch/x86/include/biosint.h b/roms/ipxe/src/arch/i386/include/biosint.h
index f47116f70..67d6a3811 100644
--- a/roms/ipxe/src/arch/x86/include/biosint.h
+++ b/roms/ipxe/src/arch/i386/include/biosint.h
@@ -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 */
diff --git a/roms/ipxe/src/arch/i386/include/bits/compiler.h b/roms/ipxe/src/arch/i386/include/bits/compiler.h
index 7c4a09396..87201135f 100644
--- a/roms/ipxe/src/arch/i386/include/bits/compiler.h
+++ b/roms/ipxe/src/arch/i386/include/bits/compiler.h
@@ -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
diff --git a/roms/ipxe/src/arch/x86/include/bits/entropy.h b/roms/ipxe/src/arch/i386/include/bits/entropy.h
index 5ac7fcd2e..bfeb5e3b5 100644
--- a/roms/ipxe/src/arch/x86/include/bits/entropy.h
+++ b/roms/ipxe/src/arch/i386/include/bits/entropy.h
@@ -3,7 +3,7 @@
/** @file
*
- * x86-specific entropy API implementations
+ * i386-specific entropy API implementations
*
*/
diff --git a/roms/ipxe/src/arch/i386/include/bits/hyperv.h b/roms/ipxe/src/arch/i386/include/bits/hyperv.h
index 0ba58afb7..3565c8a83 100644
--- a/roms/ipxe/src/arch/i386/include/bits/hyperv.h
+++ b/roms/ipxe/src/arch/i386/include/bits/hyperv.h
@@ -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 */
diff --git a/roms/ipxe/src/arch/x86/include/bits/nap.h b/roms/ipxe/src/arch/i386/include/bits/nap.h
index 7103b94c0..e8bcfd13b 100644
--- a/roms/ipxe/src/arch/x86/include/bits/nap.h
+++ b/roms/ipxe/src/arch/i386/include/bits/nap.h
@@ -3,7 +3,7 @@
/** @file
*
- * x86-specific CPU sleeping API implementations
+ * i386-specific CPU sleeping API implementations
*
*/
diff --git a/roms/ipxe/src/arch/x86/include/bits/reboot.h b/roms/ipxe/src/arch/i386/include/bits/reboot.h
index e702dd3d0..803dacfe4 100644
--- a/roms/ipxe/src/arch/x86/include/bits/reboot.h
+++ b/roms/ipxe/src/arch/i386/include/bits/reboot.h
@@ -3,7 +3,7 @@
/** @file
*
- * x86-specific reboot API implementations
+ * i386-specific reboot API implementations
*
*/
diff --git a/roms/ipxe/src/arch/x86/include/bits/sanboot.h b/roms/ipxe/src/arch/i386/include/bits/sanboot.h
index 1b9924e64..f02d2e649 100644
--- a/roms/ipxe/src/arch/x86/include/bits/sanboot.h
+++ b/roms/ipxe/src/arch/i386/include/bits/sanboot.h
@@ -3,7 +3,7 @@
/** @file
*
- * x86-specific sanboot API implementations
+ * i386-specific sanboot API implementations
*
*/
diff --git a/roms/ipxe/src/arch/x86/include/bits/smbios.h b/roms/ipxe/src/arch/i386/include/bits/smbios.h
index 9977c87ac..2ab31e74b 100644
--- a/roms/ipxe/src/arch/x86/include/bits/smbios.h
+++ b/roms/ipxe/src/arch/i386/include/bits/smbios.h
@@ -3,7 +3,7 @@
/** @file
*
- * x86-specific SMBIOS API implementations
+ * i386-specific SMBIOS API implementations
*
*/
diff --git a/roms/ipxe/src/arch/x86/include/bits/time.h b/roms/ipxe/src/arch/i386/include/bits/time.h
index 556d96f64..6a5d63d32 100644
--- a/roms/ipxe/src/arch/x86/include/bits/time.h
+++ b/roms/ipxe/src/arch/i386/include/bits/time.h
@@ -3,7 +3,7 @@
/** @file
*
- * x86-specific time API implementations
+ * i386-specific time API implementations
*
*/
diff --git a/roms/ipxe/src/arch/x86/include/bits/timer.h b/roms/ipxe/src/arch/i386/include/bits/timer.h
index b0ff5ee11..f7d86d78c 100644
--- a/roms/ipxe/src/arch/x86/include/bits/timer.h
+++ b/roms/ipxe/src/arch/i386/include/bits/timer.h
@@ -3,7 +3,7 @@
/** @file
*
- * x86-specific timer API implementations
+ * i386-specific timer API implementations
*
*/
diff --git a/roms/ipxe/src/arch/x86/include/bits/uaccess.h b/roms/ipxe/src/arch/i386/include/bits/uaccess.h
index e9e7e5af5..aac09ba95 100644
--- a/roms/ipxe/src/arch/x86/include/bits/uaccess.h
+++ b/roms/ipxe/src/arch/i386/include/bits/uaccess.h
@@ -3,7 +3,7 @@
/** @file
*
- * x86-specific user access API implementations
+ * i386-specific user access API implementations
*
*/
diff --git a/roms/ipxe/src/arch/x86/include/bits/umalloc.h b/roms/ipxe/src/arch/i386/include/bits/umalloc.h
index 5d1f554d8..113f16fd1 100644
--- a/roms/ipxe/src/arch/x86/include/bits/umalloc.h
+++ b/roms/ipxe/src/arch/i386/include/bits/umalloc.h
@@ -3,7 +3,7 @@
/** @file
*
- * x86-specific user memory allocation API implementations
+ * i386-specific user memory allocation API implementations
*
*/
diff --git a/roms/ipxe/src/arch/x86/include/bochs.h b/roms/ipxe/src/arch/i386/include/bochs.h
index 9d090fc12..9d090fc12 100644
--- a/roms/ipxe/src/arch/x86/include/bochs.h
+++ b/roms/ipxe/src/arch/i386/include/bochs.h
diff --git a/roms/ipxe/src/arch/x86/include/bootsector.h b/roms/ipxe/src/arch/i386/include/bootsector.h
index c5d35aae3..c5d35aae3 100644
--- a/roms/ipxe/src/arch/x86/include/bootsector.h
+++ b/roms/ipxe/src/arch/i386/include/bootsector.h
diff --git a/roms/ipxe/src/arch/x86/include/bzimage.h b/roms/ipxe/src/arch/i386/include/bzimage.h
index 4933ce5b1..4933ce5b1 100644
--- a/roms/ipxe/src/arch/x86/include/bzimage.h
+++ b/roms/ipxe/src/arch/i386/include/bzimage.h
diff --git a/roms/ipxe/src/arch/x86/include/comboot.h b/roms/ipxe/src/arch/i386/include/comboot.h
index 69c6ef024..2d2f04fe1 100644
--- a/roms/ipxe/src/arch/x86/include/comboot.h
+++ b/roms/ipxe/src/arch/i386/include/comboot.h
@@ -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
diff --git a/roms/ipxe/src/arch/x86/include/fakee820.h b/roms/ipxe/src/arch/i386/include/fakee820.h
index 552b1e48d..552b1e48d 100644
--- a/roms/ipxe/src/arch/x86/include/fakee820.h
+++ b/roms/ipxe/src/arch/i386/include/fakee820.h
diff --git a/roms/ipxe/src/arch/i386/include/gdbmach.h b/roms/ipxe/src/arch/i386/include/gdbmach.h
index 52cce7833..416ae341a 100644
--- a/roms/ipxe/src/arch/i386/include/gdbmach.h
+++ b/roms/ipxe/src/arch/i386/include/gdbmach.h
@@ -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;
diff --git a/roms/ipxe/src/arch/x86/include/initrd.h b/roms/ipxe/src/arch/i386/include/initrd.h
index ddb3e5a45..ddb3e5a45 100644
--- a/roms/ipxe/src/arch/x86/include/initrd.h
+++ b/roms/ipxe/src/arch/i386/include/initrd.h
diff --git a/roms/ipxe/src/arch/x86/include/int13.h b/roms/ipxe/src/arch/i386/include/int13.h
index f82a583c6..f82a583c6 100644
--- a/roms/ipxe/src/arch/x86/include/int13.h
+++ b/roms/ipxe/src/arch/i386/include/int13.h
diff --git a/roms/ipxe/src/arch/x86/include/ipxe/bios_nap.h b/roms/ipxe/src/arch/i386/include/ipxe/bios_nap.h
index c9b82c1e5..c9b82c1e5 100644
--- a/roms/ipxe/src/arch/x86/include/ipxe/bios_nap.h
+++ b/roms/ipxe/src/arch/i386/include/ipxe/bios_nap.h
diff --git a/roms/ipxe/src/arch/x86/include/ipxe/bios_reboot.h b/roms/ipxe/src/arch/i386/include/ipxe/bios_reboot.h
index 3f6df9073..3f6df9073 100644
--- a/roms/ipxe/src/arch/x86/include/ipxe/bios_reboot.h
+++ b/roms/ipxe/src/arch/i386/include/ipxe/bios_reboot.h
diff --git a/roms/ipxe/src/arch/x86/include/ipxe/bios_sanboot.h b/roms/ipxe/src/arch/i386/include/ipxe/bios_sanboot.h
index 85d698039..1a86b7d57 100644
--- a/roms/ipxe/src/arch/x86/include/ipxe/bios_sanboot.h
+++ b/roms/ipxe/src/arch/i386/include/ipxe/bios_sanboot.h
@@ -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 */
diff --git a/roms/ipxe/src/arch/x86/include/ipxe/bios_smbios.h b/roms/ipxe/src/arch/i386/include/ipxe/bios_smbios.h
index 9f7f9c8ff..9f7f9c8ff 100644
--- a/roms/ipxe/src/arch/x86/include/ipxe/bios_smbios.h
+++ b/roms/ipxe/src/arch/i386/include/ipxe/bios_smbios.h
diff --git a/roms/ipxe/src/arch/x86/include/ipxe/bios_timer.h b/roms/ipxe/src/arch/i386/include/ipxe/bios_timer.h
index 6b88a623c..6b88a623c 100644
--- a/roms/ipxe/src/arch/x86/include/ipxe/bios_timer.h
+++ b/roms/ipxe/src/arch/i386/include/ipxe/bios_timer.h
diff --git a/roms/ipxe/src/arch/x86/include/ipxe/errno/pcbios.h b/roms/ipxe/src/arch/i386/include/ipxe/errno/pcbios.h
index 6312adaa4..6312adaa4 100644
--- a/roms/ipxe/src/arch/x86/include/ipxe/errno/pcbios.h
+++ b/roms/ipxe/src/arch/i386/include/ipxe/errno/pcbios.h
diff --git a/roms/ipxe/src/arch/x86/include/ipxe/guestrpc.h b/roms/ipxe/src/arch/i386/include/ipxe/guestrpc.h
index bc3d85506..bc3d85506 100644
--- a/roms/ipxe/src/arch/x86/include/ipxe/guestrpc.h
+++ b/roms/ipxe/src/arch/i386/include/ipxe/guestrpc.h
diff --git a/roms/ipxe/src/arch/x86/include/ipxe/memtop_umalloc.h b/roms/ipxe/src/arch/i386/include/ipxe/memtop_umalloc.h
index dee055d16..dee055d16 100644
--- a/roms/ipxe/src/arch/x86/include/ipxe/memtop_umalloc.h
+++ b/roms/ipxe/src/arch/i386/include/ipxe/memtop_umalloc.h
diff --git a/roms/ipxe/src/arch/x86/include/ipxe/rdtsc_timer.h b/roms/ipxe/src/arch/i386/include/ipxe/rdtsc_timer.h
index 598f4bb08..598f4bb08 100644
--- a/roms/ipxe/src/arch/x86/include/ipxe/rdtsc_timer.h
+++ b/roms/ipxe/src/arch/i386/include/ipxe/rdtsc_timer.h
diff --git a/roms/ipxe/src/arch/x86/include/ipxe/rtc_entropy.h b/roms/ipxe/src/arch/i386/include/ipxe/rtc_entropy.h
index e214745d0..e214745d0 100644
--- a/roms/ipxe/src/arch/x86/include/ipxe/rtc_entropy.h
+++ b/roms/ipxe/src/arch/i386/include/ipxe/rtc_entropy.h
diff --git a/roms/ipxe/src/arch/x86/include/ipxe/rtc_time.h b/roms/ipxe/src/arch/i386/include/ipxe/rtc_time.h
index cb8c7f49e..cb8c7f49e 100644
--- a/roms/ipxe/src/arch/x86/include/ipxe/rtc_time.h
+++ b/roms/ipxe/src/arch/i386/include/ipxe/rtc_time.h
diff --git a/roms/ipxe/src/arch/x86/include/ipxe/vesafb.h b/roms/ipxe/src/arch/i386/include/ipxe/vesafb.h
index efc8f2cb8..efc8f2cb8 100644
--- a/roms/ipxe/src/arch/x86/include/ipxe/vesafb.h
+++ b/roms/ipxe/src/arch/i386/include/ipxe/vesafb.h
diff --git a/roms/ipxe/src/arch/x86/include/ipxe/vmware.h b/roms/ipxe/src/arch/i386/include/ipxe/vmware.h
index 24f60a03a..24f60a03a 100644
--- a/roms/ipxe/src/arch/x86/include/ipxe/vmware.h
+++ b/roms/ipxe/src/arch/i386/include/ipxe/vmware.h
diff --git a/roms/ipxe/src/arch/x86/include/kir.h b/roms/ipxe/src/arch/i386/include/kir.h
index 84633d26f..84633d26f 100644
--- a/roms/ipxe/src/arch/x86/include/kir.h
+++ b/roms/ipxe/src/arch/i386/include/kir.h
diff --git a/roms/ipxe/src/arch/x86/include/libkir.h b/roms/ipxe/src/arch/i386/include/libkir.h
index 1f5b13504..1f5b13504 100644
--- a/roms/ipxe/src/arch/x86/include/libkir.h
+++ b/roms/ipxe/src/arch/i386/include/libkir.h
diff --git a/roms/ipxe/src/arch/x86/include/librm.h b/roms/ipxe/src/arch/i386/include/librm.h
index 311748bec..a8a578a39 100644
--- a/roms/ipxe/src/arch/x86/include/librm.h
+++ b/roms/ipxe/src/arch/i386/include/librm.h
@@ -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 */
diff --git a/roms/ipxe/src/arch/x86/include/memsizes.h b/roms/ipxe/src/arch/i386/include/memsizes.h
index f115f7574..f115f7574 100644
--- a/roms/ipxe/src/arch/x86/include/memsizes.h
+++ b/roms/ipxe/src/arch/i386/include/memsizes.h
diff --git a/roms/ipxe/src/arch/x86/include/multiboot.h b/roms/ipxe/src/arch/i386/include/multiboot.h
index ae09df6c7..ae09df6c7 100644
--- a/roms/ipxe/src/arch/x86/include/multiboot.h
+++ b/roms/ipxe/src/arch/i386/include/multiboot.h
diff --git a/roms/ipxe/src/arch/x86/include/pnpbios.h b/roms/ipxe/src/arch/i386/include/pnpbios.h
index d14873700..d14873700 100644
--- a/roms/ipxe/src/arch/x86/include/pnpbios.h
+++ b/roms/ipxe/src/arch/i386/include/pnpbios.h
diff --git a/roms/ipxe/src/arch/x86/include/pxe.h b/roms/ipxe/src/arch/i386/include/pxe.h
index 54649b504..66d752683 100644
--- a/roms/ipxe/src/arch/x86/include/pxe.h
+++ b/roms/ipxe/src/arch/i386/include/pxe.h
@@ -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 );
diff --git a/roms/ipxe/src/arch/x86/include/pxe_api.h b/roms/ipxe/src/arch/i386/include/pxe_api.h
index 3110d26da..3110d26da 100644
--- a/roms/ipxe/src/arch/x86/include/pxe_api.h
+++ b/roms/ipxe/src/arch/i386/include/pxe_api.h
diff --git a/roms/ipxe/src/arch/x86/include/pxe_call.h b/roms/ipxe/src/arch/i386/include/pxe_call.h
index 2ad0a9505..cbd548318 100644
--- a/roms/ipxe/src/arch/x86/include/pxe_call.h
+++ b/roms/ipxe/src/arch/i386/include/pxe_call.h
@@ -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;
diff --git a/roms/ipxe/src/arch/x86/include/pxe_error.h b/roms/ipxe/src/arch/i386/include/pxe_error.h
index 51298e665..51298e665 100644
--- a/roms/ipxe/src/arch/x86/include/pxe_error.h
+++ b/roms/ipxe/src/arch/i386/include/pxe_error.h
diff --git a/roms/ipxe/src/arch/x86/include/pxe_types.h b/roms/ipxe/src/arch/i386/include/pxe_types.h
index 483666e33..483666e33 100644
--- a/roms/ipxe/src/arch/x86/include/pxe_types.h
+++ b/roms/ipxe/src/arch/i386/include/pxe_types.h
diff --git a/roms/ipxe/src/arch/x86/include/pxeparent.h b/roms/ipxe/src/arch/i386/include/pxeparent.h
index b31e24a76..b31e24a76 100644
--- a/roms/ipxe/src/arch/x86/include/pxeparent.h
+++ b/roms/ipxe/src/arch/i386/include/pxeparent.h
diff --git a/roms/ipxe/src/arch/x86/include/realmode.h b/roms/ipxe/src/arch/i386/include/realmode.h
index 4defd3b97..4defd3b97 100644
--- a/roms/ipxe/src/arch/x86/include/realmode.h
+++ b/roms/ipxe/src/arch/i386/include/realmode.h
diff --git a/roms/ipxe/src/arch/x86/include/registers.h b/roms/ipxe/src/arch/i386/include/registers.h
index dd3b59fd5..d9aa3c376 100644
--- a/roms/ipxe/src/arch/x86/include/registers.h
+++ b/roms/ipxe/src/arch/i386/include/registers.h
@@ -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.
*
*/
diff --git a/roms/ipxe/src/arch/x86/include/rtc.h b/roms/ipxe/src/arch/i386/include/rtc.h
index 6294b63e3..6294b63e3 100644
--- a/roms/ipxe/src/arch/x86/include/rtc.h
+++ b/roms/ipxe/src/arch/i386/include/rtc.h
diff --git a/roms/ipxe/src/arch/x86/include/sdi.h b/roms/ipxe/src/arch/i386/include/sdi.h
index 806c3f194..806c3f194 100644
--- a/roms/ipxe/src/arch/x86/include/sdi.h
+++ b/roms/ipxe/src/arch/i386/include/sdi.h
diff --git a/roms/ipxe/src/arch/i386/include/setjmp.h b/roms/ipxe/src/arch/i386/include/setjmp.h
index 98566696a..fe1a9ef4d 100644
--- a/roms/ipxe/src/arch/i386/include/setjmp.h
+++ b/roms/ipxe/src/arch/i386/include/setjmp.h
@@ -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 */
diff --git a/roms/ipxe/src/arch/x86/include/undi.h b/roms/ipxe/src/arch/i386/include/undi.h
index 7a5624f93..7a5624f93 100644
--- a/roms/ipxe/src/arch/x86/include/undi.h
+++ b/roms/ipxe/src/arch/i386/include/undi.h
diff --git a/roms/ipxe/src/arch/x86/include/undiload.h b/roms/ipxe/src/arch/i386/include/undiload.h
index 235e7a79e..235e7a79e 100644
--- a/roms/ipxe/src/arch/x86/include/undiload.h
+++ b/roms/ipxe/src/arch/i386/include/undiload.h
diff --git a/roms/ipxe/src/arch/x86/include/undinet.h b/roms/ipxe/src/arch/i386/include/undinet.h
index 2798c4466..2798c4466 100644
--- a/roms/ipxe/src/arch/x86/include/undinet.h
+++ b/roms/ipxe/src/arch/i386/include/undinet.h
diff --git a/roms/ipxe/src/arch/x86/include/undipreload.h b/roms/ipxe/src/arch/i386/include/undipreload.h
index 57f493cec..57f493cec 100644
--- a/roms/ipxe/src/arch/x86/include/undipreload.h
+++ b/roms/ipxe/src/arch/i386/include/undipreload.h
diff --git a/roms/ipxe/src/arch/x86/include/undirom.h b/roms/ipxe/src/arch/i386/include/undirom.h
index 1c530118d..1c530118d 100644
--- a/roms/ipxe/src/arch/x86/include/undirom.h
+++ b/roms/ipxe/src/arch/i386/include/undirom.h
diff --git a/roms/ipxe/src/arch/x86/include/vga.h b/roms/ipxe/src/arch/i386/include/vga.h
index 01fc39d86..01fc39d86 100644
--- a/roms/ipxe/src/arch/x86/include/vga.h
+++ b/roms/ipxe/src/arch/i386/include/vga.h
diff --git a/roms/ipxe/src/arch/x86/interface/pcbios/apm.c b/roms/ipxe/src/arch/i386/interface/pcbios/apm.c
index 50b19cb81..50b19cb81 100644
--- a/roms/ipxe/src/arch/x86/interface/pcbios/apm.c
+++ b/roms/ipxe/src/arch/i386/interface/pcbios/apm.c
diff --git a/roms/ipxe/src/arch/x86/interface/pcbios/bios_nap.c b/roms/ipxe/src/arch/i386/interface/pcbios/bios_nap.c
index f1ba8297b..f1ba8297b 100644
--- a/roms/ipxe/src/arch/x86/interface/pcbios/bios_nap.c
+++ b/roms/ipxe/src/arch/i386/interface/pcbios/bios_nap.c
diff --git a/roms/ipxe/src/arch/x86/interface/pcbios/bios_reboot.c b/roms/ipxe/src/arch/i386/interface/pcbios/bios_reboot.c
index ed18dde0b..10a1ecb89 100644
--- a/roms/ipxe/src/arch/x86/interface/pcbios/bios_reboot.c
+++ b/roms/ipxe/src/arch/i386/interface/pcbios/bios_reboot.c
@@ -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 );
diff --git a/roms/ipxe/src/arch/x86/interface/pcbios/bios_smbios.c b/roms/ipxe/src/arch/i386/interface/pcbios/bios_smbios.c
index a8c0fc325..a8c0fc325 100644
--- a/roms/ipxe/src/arch/x86/interface/pcbios/bios_smbios.c
+++ b/roms/ipxe/src/arch/i386/interface/pcbios/bios_smbios.c
diff --git a/roms/ipxe/src/arch/x86/interface/pcbios/bios_timer.c b/roms/ipxe/src/arch/i386/interface/pcbios/bios_timer.c
index 3299c9aae..3299c9aae 100644
--- a/roms/ipxe/src/arch/x86/interface/pcbios/bios_timer.c
+++ b/roms/ipxe/src/arch/i386/interface/pcbios/bios_timer.c
diff --git a/roms/ipxe/src/arch/x86/interface/pcbios/biosint.c b/roms/ipxe/src/arch/i386/interface/pcbios/biosint.c
index 667e9ed81..3b8e80438 100644
--- a/roms/ipxe/src/arch/x86/interface/pcbios/biosint.c
+++ b/roms/ipxe/src/arch/i386/interface/pcbios/biosint.c
@@ -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;
-}
diff --git a/roms/ipxe/src/arch/x86/interface/pcbios/int13.c b/roms/ipxe/src/arch/i386/interface/pcbios/int13.c
index 6f16904df..f0450da90 100644
--- a/roms/ipxe/src/arch/x86/interface/pcbios/int13.c
+++ b/roms/ipxe/src/arch/i386/interface/pcbios/int13.c
@@ -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 );
diff --git a/roms/ipxe/src/arch/x86/interface/pcbios/int13con.c b/roms/ipxe/src/arch/i386/interface/pcbios/int13con.c
index 2414c6909..2414c6909 100644
--- a/roms/ipxe/src/arch/x86/interface/pcbios/int13con.c
+++ b/roms/ipxe/src/arch/i386/interface/pcbios/int13con.c
diff --git a/roms/ipxe/src/arch/x86/interface/pcbios/memtop_umalloc.c b/roms/ipxe/src/arch/i386/interface/pcbios/memtop_umalloc.c
index f1ab73e29..957f8e324 100644
--- a/roms/ipxe/src/arch/x86/interface/pcbios/memtop_umalloc.c
+++ b/roms/ipxe/src/arch/i386/interface/pcbios/memtop_umalloc.c
@@ -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
*
*/
diff --git a/roms/ipxe/src/arch/x86/interface/pcbios/pcibios.c b/roms/ipxe/src/arch/i386/interface/pcbios/pcibios.c
index 07ac0c18d..34efa0b39 100644
--- a/roms/ipxe/src/arch/x86/interface/pcbios/pcibios.c
+++ b/roms/ipxe/src/arch/i386/interface/pcbios/pcibios.c
@@ -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 );
diff --git a/roms/ipxe/src/arch/x86/interface/pcbios/rtc_entropy.c b/roms/ipxe/src/arch/i386/interface/pcbios/rtc_entropy.c
index 83c2445f8..9aab03c03 100644
--- a/roms/ipxe/src/arch/x86/interface/pcbios/rtc_entropy.c
+++ b/roms/ipxe/src/arch/i386/interface/pcbios/rtc_entropy.c
@@ -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 );
}
diff --git a/roms/ipxe/src/arch/x86/interface/pcbios/rtc_time.c b/roms/ipxe/src/arch/i386/interface/pcbios/rtc_time.c
index cdbeac8d5..cdbeac8d5 100644
--- a/roms/ipxe/src/arch/x86/interface/pcbios/rtc_time.c
+++ b/roms/ipxe/src/arch/i386/interface/pcbios/rtc_time.c
diff --git a/roms/ipxe/src/arch/x86/interface/pcbios/vesafb.c b/roms/ipxe/src/arch/i386/interface/pcbios/vesafb.c
index 50e485852..9cf2bf29e 100644
--- a/roms/ipxe/src/arch/x86/interface/pcbios/vesafb.c
+++ b/roms/ipxe/src/arch/i386/interface/pcbios/vesafb.c
@@ -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 );
diff --git a/roms/ipxe/src/arch/x86/interface/pxe/pxe_call.c b/roms/ipxe/src/arch/i386/interface/pxe/pxe_call.c
index 671182991..104313666 100644
--- a/roms/ipxe/src/arch/x86/interface/pxe/pxe_call.c
+++ b/roms/ipxe/src/arch/i386/interface/pxe/pxe_call.c
@@ -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 );
diff --git a/roms/ipxe/src/arch/x86/interface/pxe/pxe_entry.S b/roms/ipxe/src/arch/i386/interface/pxe/pxe_entry.S
index 663aa842e..07852cd50 100644
--- a/roms/ipxe/src/arch/x86/interface/pxe/pxe_entry.S
+++ b/roms/ipxe/src/arch/i386/interface/pxe/pxe_entry.S
@@ -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
diff --git a/roms/ipxe/src/arch/x86/interface/pxe/pxe_exit_hook.c b/roms/ipxe/src/arch/i386/interface/pxe/pxe_exit_hook.c
index f92dae0d1..f92dae0d1 100644
--- a/roms/ipxe/src/arch/x86/interface/pxe/pxe_exit_hook.c
+++ b/roms/ipxe/src/arch/i386/interface/pxe/pxe_exit_hook.c
diff --git a/roms/ipxe/src/arch/x86/interface/pxe/pxe_file.c b/roms/ipxe/src/arch/i386/interface/pxe/pxe_file.c
index 456ffb5fd..456ffb5fd 100644
--- a/roms/ipxe/src/arch/x86/interface/pxe/pxe_file.c
+++ b/roms/ipxe/src/arch/i386/interface/pxe/pxe_file.c
diff --git a/roms/ipxe/src/arch/x86/interface/pxe/pxe_loader.c b/roms/ipxe/src/arch/i386/interface/pxe/pxe_loader.c
index e6a2e072a..e6a2e072a 100644
--- a/roms/ipxe/src/arch/x86/interface/pxe/pxe_loader.c
+++ b/roms/ipxe/src/arch/i386/interface/pxe/pxe_loader.c
diff --git a/roms/ipxe/src/arch/x86/interface/pxe/pxe_preboot.c b/roms/ipxe/src/arch/i386/interface/pxe/pxe_preboot.c
index 09e721b34..6e09080bc 100644
--- a/roms/ipxe/src/arch/x86/interface/pxe/pxe_preboot.c
+++ b/roms/ipxe/src/arch/i386/interface/pxe/pxe_preboot.c
@@ -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
diff --git a/roms/ipxe/src/arch/x86/interface/pxe/pxe_tftp.c b/roms/ipxe/src/arch/i386/interface/pxe/pxe_tftp.c
index 3b4c6d847..068d8a7b2 100644
--- a/roms/ipxe/src/arch/x86/interface/pxe/pxe_tftp.c
+++ b/roms/ipxe/src/arch/i386/interface/pxe/pxe_tftp.c
@@ -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;
diff --git a/roms/ipxe/src/arch/x86/interface/pxe/pxe_udp.c b/roms/ipxe/src/arch/i386/interface/pxe/pxe_udp.c
index 5a04f0865..071cb59db 100644
--- a/roms/ipxe/src/arch/x86/interface/pxe/pxe_udp.c
+++ b/roms/ipxe/src/arch/i386/interface/pxe/pxe_udp.c
@@ -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 ) {
diff --git a/roms/ipxe/src/arch/x86/interface/pxe/pxe_undi.c b/roms/ipxe/src/arch/i386/interface/pxe/pxe_undi.c
index 2eb68178a..2eb68178a 100644
--- a/roms/ipxe/src/arch/x86/interface/pxe/pxe_undi.c
+++ b/roms/ipxe/src/arch/i386/interface/pxe/pxe_undi.c
diff --git a/roms/ipxe/src/arch/x86/interface/pxeparent/pxeparent.c b/roms/ipxe/src/arch/i386/interface/pxeparent/pxeparent.c
index cc6101c1f..0b6be9a03 100644
--- a/roms/ipxe/src/arch/x86/interface/pxeparent/pxeparent.c
+++ b/roms/ipxe/src/arch/i386/interface/pxeparent/pxeparent.c
@@ -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
diff --git a/roms/ipxe/src/arch/x86/interface/syslinux/com32_call.c b/roms/ipxe/src/arch/i386/interface/syslinux/com32_call.c
index 19fdbaff9..75dcc238f 100644
--- a/roms/ipxe/src/arch/x86/interface/syslinux/com32_call.c
+++ b/roms/ipxe/src/arch/i386/interface/syslinux/com32_call.c
@@ -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 );
diff --git a/roms/ipxe/src/arch/x86/interface/syslinux/com32_wrapper.S b/roms/ipxe/src/arch/i386/interface/syslinux/com32_wrapper.S
index d59a3392c..c9d1452b4 100644
--- a/roms/ipxe/src/arch/x86/interface/syslinux/com32_wrapper.S
+++ b/roms/ipxe/src/arch/i386/interface/syslinux/com32_wrapper.S
@@ -19,82 +19,79 @@
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
diff --git a/roms/ipxe/src/arch/x86/interface/syslinux/comboot_call.c b/roms/ipxe/src/arch/i386/interface/syslinux/comboot_call.c
index 2f5c252c1..69d94c407 100644
--- a/roms/ipxe/src/arch/x86/interface/syslinux/comboot_call.c
+++ b/roms/ipxe/src/arch/i386/interface/syslinux/comboot_call.c
@@ -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 );
}
diff --git a/roms/ipxe/src/arch/x86/interface/syslinux/comboot_resolv.c b/roms/ipxe/src/arch/i386/interface/syslinux/comboot_resolv.c
index 03bbfd04a..03bbfd04a 100644
--- a/roms/ipxe/src/arch/x86/interface/syslinux/comboot_resolv.c
+++ b/roms/ipxe/src/arch/i386/interface/syslinux/comboot_resolv.c
diff --git a/roms/ipxe/src/arch/x86/interface/vmware/guestinfo.c b/roms/ipxe/src/arch/i386/interface/vmware/guestinfo.c
index a0530c8d1..a0530c8d1 100644
--- a/roms/ipxe/src/arch/x86/interface/vmware/guestinfo.c
+++ b/roms/ipxe/src/arch/i386/interface/vmware/guestinfo.c
diff --git a/roms/ipxe/src/arch/x86/interface/vmware/guestrpc.c b/roms/ipxe/src/arch/i386/interface/vmware/guestrpc.c
index ef7ee8151..ef7ee8151 100644
--- a/roms/ipxe/src/arch/x86/interface/vmware/guestrpc.c
+++ b/roms/ipxe/src/arch/i386/interface/vmware/guestrpc.c
diff --git a/roms/ipxe/src/arch/x86/interface/vmware/vmconsole.c b/roms/ipxe/src/arch/i386/interface/vmware/vmconsole.c
index f7df4f75b..f7df4f75b 100644
--- a/roms/ipxe/src/arch/x86/interface/vmware/vmconsole.c
+++ b/roms/ipxe/src/arch/i386/interface/vmware/vmconsole.c
diff --git a/roms/ipxe/src/arch/x86/interface/vmware/vmware.c b/roms/ipxe/src/arch/i386/interface/vmware/vmware.c
index a415465fb..a415465fb 100644
--- a/roms/ipxe/src/arch/x86/interface/vmware/vmware.c
+++ b/roms/ipxe/src/arch/i386/interface/vmware/vmware.c
diff --git a/roms/ipxe/src/arch/x86/prefix/bootpart.S b/roms/ipxe/src/arch/i386/prefix/bootpart.S
index 6d0c6034a..6d0c6034a 100644
--- a/roms/ipxe/src/arch/x86/prefix/bootpart.S
+++ b/roms/ipxe/src/arch/i386/prefix/bootpart.S
diff --git a/roms/ipxe/src/arch/x86/prefix/dskprefix.S b/roms/ipxe/src/arch/i386/prefix/dskprefix.S
index 0503f113d..7aa017ccd 100644
--- a/roms/ipxe/src/arch/x86/prefix/dskprefix.S
+++ b/roms/ipxe/src/arch/i386/prefix/dskprefix.S
@@ -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
diff --git a/roms/ipxe/src/arch/x86/prefix/exeprefix.S b/roms/ipxe/src/arch/i386/prefix/exeprefix.S
index c351456e2..5c648d51d 100644
--- a/roms/ipxe/src/arch/x86/prefix/exeprefix.S
+++ b/roms/ipxe/src/arch/i386/prefix/exeprefix.S
@@ -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
diff --git a/roms/ipxe/src/arch/x86/prefix/hdprefix.S b/roms/ipxe/src/arch/i386/prefix/hdprefix.S
index 24f5d3850..1d012d80b 100644
--- a/roms/ipxe/src/arch/x86/prefix/hdprefix.S
+++ b/roms/ipxe/src/arch/i386/prefix/hdprefix.S
@@ -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
diff --git a/roms/ipxe/src/arch/x86/prefix/isaromprefix.S b/roms/ipxe/src/arch/i386/prefix/isaromprefix.S
index fb49819ee..fb49819ee 100644
--- a/roms/ipxe/src/arch/x86/prefix/isaromprefix.S
+++ b/roms/ipxe/src/arch/i386/prefix/isaromprefix.S
diff --git a/roms/ipxe/src/arch/x86/prefix/kkkpxeprefix.S b/roms/ipxe/src/arch/i386/prefix/kkkpxeprefix.S
index 6e43cd26a..6e43cd26a 100644
--- a/roms/ipxe/src/arch/x86/prefix/kkkpxeprefix.S
+++ b/roms/ipxe/src/arch/i386/prefix/kkkpxeprefix.S
diff --git a/roms/ipxe/src/arch/x86/prefix/kkpxeprefix.S b/roms/ipxe/src/arch/i386/prefix/kkpxeprefix.S
index 3c17dbdb1..3c17dbdb1 100644
--- a/roms/ipxe/src/arch/x86/prefix/kkpxeprefix.S
+++ b/roms/ipxe/src/arch/i386/prefix/kkpxeprefix.S
diff --git a/roms/ipxe/src/arch/x86/prefix/kpxeprefix.S b/roms/ipxe/src/arch/i386/prefix/kpxeprefix.S
index 200006d83..200006d83 100644
--- a/roms/ipxe/src/arch/x86/prefix/kpxeprefix.S
+++ b/roms/ipxe/src/arch/i386/prefix/kpxeprefix.S
diff --git a/roms/ipxe/src/arch/x86/prefix/libprefix.S b/roms/ipxe/src/arch/i386/prefix/libprefix.S
index 533be981e..7d5c1ed53 100644
--- a/roms/ipxe/src/arch/x86/prefix/libprefix.S
+++ b/roms/ipxe/src/arch/i386/prefix/libprefix.S
@@ -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:
diff --git a/roms/ipxe/src/arch/x86/prefix/lkrnprefix.S b/roms/ipxe/src/arch/i386/prefix/lkrnprefix.S
index 922181f0e..64135e14b 100644
--- a/roms/ipxe/src/arch/x86/prefix/lkrnprefix.S
+++ b/roms/ipxe/src/arch/i386/prefix/lkrnprefix.S
@@ -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
diff --git a/roms/ipxe/src/arch/x86/prefix/mbr.S b/roms/ipxe/src/arch/i386/prefix/mbr.S
index a1e237de8..a1e237de8 100644
--- a/roms/ipxe/src/arch/x86/prefix/mbr.S
+++ b/roms/ipxe/src/arch/i386/prefix/mbr.S
diff --git a/roms/ipxe/src/arch/x86/prefix/mromprefix.S b/roms/ipxe/src/arch/i386/prefix/mromprefix.S
index b636b92af..b636b92af 100644
--- a/roms/ipxe/src/arch/x86/prefix/mromprefix.S
+++ b/roms/ipxe/src/arch/i386/prefix/mromprefix.S
diff --git a/roms/ipxe/src/arch/x86/prefix/nbiprefix.S b/roms/ipxe/src/arch/i386/prefix/nbiprefix.S
index de38e4af6..16c79566c 100644
--- a/roms/ipxe/src/arch/x86/prefix/nbiprefix.S
+++ b/roms/ipxe/src/arch/i386/prefix/nbiprefix.S
@@ -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
diff --git a/roms/ipxe/src/arch/x86/prefix/nullprefix.S b/roms/ipxe/src/arch/i386/prefix/nullprefix.S
index bd0ff339e..bd0ff339e 100644
--- a/roms/ipxe/src/arch/x86/prefix/nullprefix.S
+++ b/roms/ipxe/src/arch/i386/prefix/nullprefix.S
diff --git a/roms/ipxe/src/arch/x86/prefix/pciromprefix.S b/roms/ipxe/src/arch/i386/prefix/pciromprefix.S
index 5a5a49647..5a5a49647 100644
--- a/roms/ipxe/src/arch/x86/prefix/pciromprefix.S
+++ b/roms/ipxe/src/arch/i386/prefix/pciromprefix.S
diff --git a/roms/ipxe/src/arch/x86/prefix/pxeprefix.S b/roms/ipxe/src/arch/i386/prefix/pxeprefix.S
index 52ea18039..465ce4345 100644
--- a/roms/ipxe/src/arch/x86/prefix/pxeprefix.S
+++ b/roms/ipxe/src/arch/i386/prefix/pxeprefix.S
@@ -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
diff --git a/roms/ipxe/src/arch/x86/prefix/romprefix.S b/roms/ipxe/src/arch/i386/prefix/romprefix.S
index f4ca20677..18dda2b37 100644
--- a/roms/ipxe/src/arch/x86/prefix/romprefix.S
+++ b/roms/ipxe/src/arch/i386/prefix/romprefix.S
@@ -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
diff --git a/roms/ipxe/src/arch/x86/prefix/undiloader.S b/roms/ipxe/src/arch/i386/prefix/undiloader.S
index 530b48e8a..5cace44b7 100644
--- a/roms/ipxe/src/arch/x86/prefix/undiloader.S
+++ b/roms/ipxe/src/arch/i386/prefix/undiloader.S
@@ -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
diff --git a/roms/ipxe/src/arch/x86/prefix/unlzma.S b/roms/ipxe/src/arch/i386/prefix/unlzma.S
index ce18c756f..8d4b3c1a8 100644
--- a/roms/ipxe/src/arch/x86/prefix/unlzma.S
+++ b/roms/ipxe/src/arch/i386/prefix/unlzma.S
@@ -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
diff --git a/roms/ipxe/src/arch/x86/prefix/unlzma16.S b/roms/ipxe/src/arch/i386/prefix/unlzma16.S
index 32b43f0dc..32b43f0dc 100644
--- a/roms/ipxe/src/arch/x86/prefix/unlzma16.S
+++ b/roms/ipxe/src/arch/i386/prefix/unlzma16.S
diff --git a/roms/ipxe/src/arch/x86/prefix/usbdisk.S b/roms/ipxe/src/arch/i386/prefix/usbdisk.S
index 9676406e2..9676406e2 100644
--- a/roms/ipxe/src/arch/x86/prefix/usbdisk.S
+++ b/roms/ipxe/src/arch/i386/prefix/usbdisk.S
diff --git a/roms/ipxe/src/arch/x86/scripts/pcbios.lds b/roms/ipxe/src/arch/i386/scripts/i386.lds
index c9a91c02b..38c89e14b 100644
--- a/roms/ipxe/src/arch/x86/scripts/pcbios.lds
+++ b/roms/ipxe/src/arch/i386/scripts/i386.lds
@@ -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/x86/transitions/liba20.S b/roms/ipxe/src/arch/i386/transitions/liba20.S
index 6c1e1f62f..6c1e1f62f 100644
--- a/roms/ipxe/src/arch/x86/transitions/liba20.S
+++ b/roms/ipxe/src/arch/i386/transitions/liba20.S
diff --git a/roms/ipxe/src/arch/x86/transitions/libkir.S b/roms/ipxe/src/arch/i386/transitions/libkir.S
index fa9459d52..fa9459d52 100644
--- a/roms/ipxe/src/arch/x86/transitions/libkir.S
+++ b/roms/ipxe/src/arch/i386/transitions/libkir.S
diff --git a/roms/ipxe/src/arch/x86/transitions/libpm.S b/roms/ipxe/src/arch/i386/transitions/libpm.S
index e69de29bb..e69de29bb 100644
--- a/roms/ipxe/src/arch/x86/transitions/libpm.S
+++ b/roms/ipxe/src/arch/i386/transitions/libpm.S
diff --git a/roms/ipxe/src/arch/i386/transitions/librm.S b/roms/ipxe/src/arch/i386/transitions/librm.S
new file mode 100644
index 000000000..863e22415
--- /dev/null
+++ b/roms/ipxe/src/arch/i386/transitions/librm.S
@@ -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
index 000000000..becb02677
--- /dev/null
+++ b/roms/ipxe/src/arch/i386/transitions/librm_mgmt.c
@@ -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 );
diff --git a/roms/ipxe/src/arch/x86/transitions/librm_test.c b/roms/ipxe/src/arch/i386/transitions/librm_test.c
index ba4254fe4..f1a517eda 100644
--- a/roms/ipxe/src/arch/x86/transitions/librm_test.c
+++ b/roms/ipxe/src/arch/i386/transitions/librm_test.c
@@ -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 );
}
}
diff --git a/roms/ipxe/src/arch/x86/Makefile b/roms/ipxe/src/arch/x86/Makefile
index 368c29f6d..98c49b98d 100644
--- a/roms/ipxe/src/arch/x86/Makefile
+++ b/roms/ipxe/src/arch/x86/Makefile
@@ -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
diff --git a/roms/ipxe/src/arch/x86/Makefile.efi b/roms/ipxe/src/arch/x86/Makefile.efi
index f04be425b..f73bc7d5d 100644
--- a/roms/ipxe/src/arch/x86/Makefile.efi
+++ b/roms/ipxe/src/arch/x86/Makefile.efi
@@ -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
index f8c225352..000000000
--- a/roms/ipxe/src/arch/x86/Makefile.pcbios
+++ /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
index af6abfedd..000000000
--- a/roms/ipxe/src/arch/x86/core/gdbmach.c
+++ /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] );
- }
-}
diff --git a/roms/ipxe/src/arch/x86/core/pcidirect.c b/roms/ipxe/src/arch/x86/core/pcidirect.c
index 0d09be84b..9b8e6b1d9 100644
--- a/roms/ipxe/src/arch/x86/core/pcidirect.c
+++ b/roms/ipxe/src/arch/x86/core/pcidirect.c
@@ -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 );
}
diff --git a/roms/ipxe/src/arch/x86/core/x86_io.c b/roms/ipxe/src/arch/x86/core/x86_io.c
index 6c6b6e1e7..3081fa8b9 100644
--- a/roms/ipxe/src/arch/x86/core/x86_io.c
+++ b/roms/ipxe/src/arch/x86/core/x86_io.c
@@ -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 );
diff --git a/roms/ipxe/src/arch/x86/core/x86_tcpip.c b/roms/ipxe/src/arch/x86/core/x86_tcpip.c
index ed323d5d0..88042f5f7 100644
--- a/roms/ipxe/src/arch/x86/core/x86_tcpip.c
+++ b/roms/ipxe/src/arch/x86/core/x86_tcpip.c
@@ -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
index 17dcf1024..000000000
--- a/roms/ipxe/src/arch/x86/include/bits/bitops.h
+++ /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 */
diff --git a/roms/ipxe/src/arch/x86/include/bits/errfile.h b/roms/ipxe/src/arch/x86/include/bits/errfile.h
index 42792242d..0d1617d20 100644
--- a/roms/ipxe/src/arch/x86/include/bits/errfile.h
+++ b/roms/ipxe/src/arch/x86/include/bits/errfile.h
@@ -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
index d6fff257e..000000000
--- a/roms/ipxe/src/arch/x86/include/bits/iomap.h
+++ /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 */
diff --git a/roms/ipxe/src/arch/x86/include/bits/tcpip.h b/roms/ipxe/src/arch/x86/include/bits/tcpip.h
index 0ac55b1a0..5c2baffcf 100644
--- a/roms/ipxe/src/arch/x86/include/bits/tcpip.h
+++ b/roms/ipxe/src/arch/x86/include/bits/tcpip.h
@@ -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 */
diff --git a/roms/ipxe/src/arch/x86/include/bits/xen.h b/roms/ipxe/src/arch/x86/include/bits/xen.h
index 3433cea1f..fc065ea38 100644
--- a/roms/ipxe/src/arch/x86/include/bits/xen.h
+++ b/roms/ipxe/src/arch/x86/include/bits/xen.h
@@ -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
index 18e0a3002..000000000
--- a/roms/ipxe/src/arch/x86/include/ipxe/iomap_pages.h
+++ /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 */
diff --git a/roms/ipxe/src/arch/x86/include/ipxe/x86_io.h b/roms/ipxe/src/arch/x86/include/ipxe/x86_io.h
index a6ebe1f4c..5214e9fbb 100644
--- a/roms/ipxe/src/arch/x86/include/ipxe/x86_io.h
+++ b/roms/ipxe/src/arch/x86/include/ipxe/x86_io.h
@@ -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
index 3470be477..000000000
--- a/roms/ipxe/src/arch/x86/include/rmsetjmp.h
+++ /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 */
diff --git a/roms/ipxe/src/interface/efi/efi_entropy.c b/roms/ipxe/src/arch/x86/interface/efi/efi_entropy.c
index 881c4c9a2..a54bd12e6 100644
--- a/roms/ipxe/src/interface/efi/efi_entropy.c
+++ b/roms/ipxe/src/arch/x86/interface/efi/efi_entropy.c
@@ -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/interface/efi/efidrvprefix.c b/roms/ipxe/src/arch/x86/prefix/efidrvprefix.c
index 4fbb19ff7..4fbb19ff7 100644
--- a/roms/ipxe/src/interface/efi/efidrvprefix.c
+++ b/roms/ipxe/src/arch/x86/prefix/efidrvprefix.c
diff --git a/roms/ipxe/src/interface/efi/efiprefix.c b/roms/ipxe/src/arch/x86/prefix/efiprefix.c
index 18b931e68..18b931e68 100644
--- a/roms/ipxe/src/interface/efi/efiprefix.c
+++ b/roms/ipxe/src/arch/x86/prefix/efiprefix.c
diff --git a/roms/ipxe/src/scripts/efi.lds b/roms/ipxe/src/arch/x86/scripts/efi.lds
index f1049f24b..f1049f24b 100644
--- a/roms/ipxe/src/scripts/efi.lds
+++ b/roms/ipxe/src/arch/x86/scripts/efi.lds
diff --git a/roms/ipxe/src/arch/x86/transitions/librm.S b/roms/ipxe/src/arch/x86/transitions/librm.S
deleted file mode 100644
index e91ede372..000000000
--- a/roms/ipxe/src/arch/x86/transitions/librm.S
+++ /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
index 8776f2854..000000000
--- a/roms/ipxe/src/arch/x86/transitions/librm_mgmt.c
+++ /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 );
diff --git a/roms/ipxe/src/arch/x86_64/Makefile b/roms/ipxe/src/arch/x86_64/Makefile
index 246905cdb..48c0aa1af 100644
--- a/roms/ipxe/src/arch/x86_64/Makefile
+++ b/roms/ipxe/src/arch/x86_64/Makefile
@@ -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
diff --git a/roms/ipxe/src/arch/x86_64/Makefile.efi b/roms/ipxe/src/arch/x86_64/Makefile.efi
index 0041bb8f0..26b712780 100644
--- a/roms/ipxe/src/arch/x86_64/Makefile.efi
+++ b/roms/ipxe/src/arch/x86_64/Makefile.efi
@@ -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
index ba4c8d8dc..000000000
--- a/roms/ipxe/src/arch/x86_64/Makefile.pcbios
+++ /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
index 89280bf89..000000000
--- a/roms/ipxe/src/arch/x86_64/core/gdbidt.S
+++ /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
diff --git a/roms/ipxe/src/arch/x86_64/include/bits/compiler.h b/roms/ipxe/src/arch/x86_64/include/bits/compiler.h
index 98c560e7d..f70b2e517 100644
--- a/roms/ipxe/src/arch/x86_64/include/bits/compiler.h
+++ b/roms/ipxe/src/arch/x86_64/include/bits/compiler.h
@@ -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
diff --git a/roms/ipxe/src/arch/arm/include/bits/entropy.h b/roms/ipxe/src/arch/x86_64/include/bits/entropy.h
index 75fdc90ea..a9b3bc10e 100644
--- a/roms/ipxe/src/arch/arm/include/bits/entropy.h
+++ b/roms/ipxe/src/arch/x86_64/include/bits/entropy.h
@@ -3,7 +3,7 @@
/** @file
*
- * ARM-specific entropy API implementations
+ * x86_64-specific entropy API implementations
*
*/
diff --git a/roms/ipxe/src/arch/x86_64/include/bits/hyperv.h b/roms/ipxe/src/arch/x86_64/include/bits/hyperv.h
index 975b1eee0..845c182f7 100644
--- a/roms/ipxe/src/arch/x86_64/include/bits/hyperv.h
+++ b/roms/ipxe/src/arch/x86_64/include/bits/hyperv.h
@@ -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
index 000000000..8b42c0a4a
--- /dev/null
+++ b/roms/ipxe/src/arch/x86_64/include/bits/nap.h
@@ -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 */
diff --git a/roms/ipxe/src/arch/arm/include/bits/reboot.h b/roms/ipxe/src/arch/x86_64/include/bits/reboot.h
index 88c50250c..f9bcd6a7b 100644
--- a/roms/ipxe/src/arch/arm/include/bits/reboot.h
+++ b/roms/ipxe/src/arch/x86_64/include/bits/reboot.h
@@ -3,7 +3,7 @@
/** @file
*
- * ARM-specific reboot API implementations
+ * x86_64-specific reboot API implementations
*
*/
diff --git a/roms/ipxe/src/arch/arm/include/bits/sanboot.h b/roms/ipxe/src/arch/x86_64/include/bits/sanboot.h
index abd4c79a5..dcab830f6 100644
--- a/roms/ipxe/src/arch/arm/include/bits/sanboot.h
+++ b/roms/ipxe/src/arch/x86_64/include/bits/sanboot.h
@@ -3,7 +3,7 @@
/** @file
*
- * ARM-specific sanboot API implementations
+ * x86_64-specific sanboot API implementations
*
*/
diff --git a/roms/ipxe/src/arch/arm/include/bits/smbios.h b/roms/ipxe/src/arch/x86_64/include/bits/smbios.h
index d94218116..2f0118d02 100644
--- a/roms/ipxe/src/arch/arm/include/bits/smbios.h
+++ b/roms/ipxe/src/arch/x86_64/include/bits/smbios.h
@@ -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 */
diff --git a/roms/ipxe/src/arch/arm/include/bits/time.h b/roms/ipxe/src/arch/x86_64/include/bits/time.h
index 724d8b932..aa74fac8c 100644
--- a/roms/ipxe/src/arch/arm/include/bits/time.h
+++ b/roms/ipxe/src/arch/x86_64/include/bits/time.h
@@ -3,7 +3,7 @@
/** @file
*
- * ARM-specific time API implementations
+ * x86_64-specific time API implementations
*
*/
diff --git a/roms/ipxe/src/arch/arm/include/bits/timer.h b/roms/ipxe/src/arch/x86_64/include/bits/timer.h
index 64e7d31df..dfa6c270c 100644
--- a/roms/ipxe/src/arch/arm/include/bits/timer.h
+++ b/roms/ipxe/src/arch/x86_64/include/bits/timer.h
@@ -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 */
diff --git a/roms/ipxe/src/arch/arm/include/bits/uaccess.h b/roms/ipxe/src/arch/x86_64/include/bits/uaccess.h
index 87f11509c..455829242 100644
--- a/roms/ipxe/src/arch/arm/include/bits/uaccess.h
+++ b/roms/ipxe/src/arch/x86_64/include/bits/uaccess.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
index 000000000..12bf949d1
--- /dev/null
+++ b/roms/ipxe/src/arch/x86_64/include/bits/umalloc.h
@@ -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 */
diff --git a/roms/ipxe/src/arch/x86_64/include/gdbmach.h b/roms/ipxe/src/arch/x86_64/include/gdbmach.h
index 367405fd6..6dadbbdd3 100644
--- a/roms/ipxe/src/arch/x86_64/include/gdbmach.h
+++ b/roms/ipxe/src/arch/x86_64/include/gdbmach.h
@@ -14,37 +14,16 @@
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
index e07e4c192..000000000
--- a/roms/ipxe/src/arch/x86_64/include/pcbios/ipxe/dhcp_arch.h
+++ /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
index d857d71df..000000000
--- a/roms/ipxe/src/config/cloud/aws.ipxe
+++ /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
index e69de29bb..000000000
--- a/roms/ipxe/src/config/cloud/colour.h
+++ /dev/null
diff --git a/roms/ipxe/src/config/cloud/console.h b/roms/ipxe/src/config/cloud/console.h
deleted file mode 100644
index dae18e556..000000000
--- a/roms/ipxe/src/config/cloud/console.h
+++ /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
index e69de29bb..000000000
--- a/roms/ipxe/src/config/cloud/crypto.h
+++ /dev/null
diff --git a/roms/ipxe/src/config/cloud/general.h b/roms/ipxe/src/config/cloud/general.h
deleted file mode 100644
index e69de29bb..000000000
--- a/roms/ipxe/src/config/cloud/general.h
+++ /dev/null
diff --git a/roms/ipxe/src/config/cloud/serial.h b/roms/ipxe/src/config/cloud/serial.h
deleted file mode 100644
index e69de29bb..000000000
--- a/roms/ipxe/src/config/cloud/serial.h
+++ /dev/null
diff --git a/roms/ipxe/src/config/cloud/settings.h b/roms/ipxe/src/config/cloud/settings.h
deleted file mode 100644
index e69de29bb..000000000
--- a/roms/ipxe/src/config/cloud/settings.h
+++ /dev/null
diff --git a/roms/ipxe/src/config/cloud/sideband.h b/roms/ipxe/src/config/cloud/sideband.h
deleted file mode 100644
index e69de29bb..000000000
--- a/roms/ipxe/src/config/cloud/sideband.h
+++ /dev/null
diff --git a/roms/ipxe/src/config/cloud/usb.h b/roms/ipxe/src/config/cloud/usb.h
deleted file mode 100644
index e69de29bb..000000000
--- a/roms/ipxe/src/config/cloud/usb.h
+++ /dev/null
diff --git a/roms/ipxe/src/config/config.c b/roms/ipxe/src/config/config.c
index e24cfe0d0..1dd912c1d 100644
--- a/roms/ipxe/src/config/config.c
+++ b/roms/ipxe/src/config/config.c
@@ -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
index 92678d12d..000000000
--- a/roms/ipxe/src/config/config_efi.c
+++ /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
diff --git a/roms/ipxe/src/config/config_ethernet.c b/roms/ipxe/src/config/config_ethernet.c
index b5f7ddc9d..de7a07c57 100644
--- a/roms/ipxe/src/config/config_ethernet.c
+++ b/roms/ipxe/src/config/config_ethernet.c
@@ -43,6 +43,3 @@ REQUIRE_OBJECT ( fcoe );
#ifdef NET_PROTO_STP
REQUIRE_OBJECT ( stp );
#endif
-#ifdef NET_PROTO_LACP
-REQUIRE_OBJECT ( eth_slow );
-#endif
diff --git a/roms/ipxe/src/config/config_infiniband.c b/roms/ipxe/src/config/config_infiniband.c
index 4da8fe219..a742e7559 100644
--- a/roms/ipxe/src/config/config_infiniband.c
+++ b/roms/ipxe/src/config/config_infiniband.c
@@ -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
index 71eeff9e7..000000000
--- a/roms/ipxe/src/config/config_linux.c
+++ /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
index 698c68a8d..000000000
--- a/roms/ipxe/src/config/config_pcbios.c
+++ /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
diff --git a/roms/ipxe/src/config/config_usb.c b/roms/ipxe/src/config/config_usb.c
index 17296d277..dc0e6e6af 100644
--- a/roms/ipxe/src/config/config_usb.c
+++ b/roms/ipxe/src/config/config_usb.c
@@ -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
diff --git a/roms/ipxe/src/config/console.h b/roms/ipxe/src/config/console.h
index 9f770d094..ffa5cf50d 100644
--- a/roms/ipxe/src/config/console.h
+++ b/roms/ipxe/src/config/console.h
@@ -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>
diff --git a/roms/ipxe/src/config/crypto.h b/roms/ipxe/src/config/crypto.h
index 8f885c554..bccfc04b8 100644
--- a/roms/ipxe/src/config/crypto.h
+++ b/roms/ipxe/src/config/crypto.h
@@ -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>
diff --git a/roms/ipxe/src/config/defaults/efi.h b/roms/ipxe/src/config/defaults/efi.h
index ba4eed936..cdf41c54d 100644
--- a/roms/ipxe/src/config/defaults/efi.h
+++ b/roms/ipxe/src/config/defaults/efi.h
@@ -10,10 +10,11 @@
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 */
diff --git a/roms/ipxe/src/config/defaults/pcbios.h b/roms/ipxe/src/config/defaults/pcbios.h
index e1915054c..3ed8343ce 100644
--- a/roms/ipxe/src/config/defaults/pcbios.h
+++ b/roms/ipxe/src/config/defaults/pcbios.h
@@ -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 */
diff --git a/roms/ipxe/src/config/dhcp.h b/roms/ipxe/src/config/dhcp.h
index bff5b56d6..49fe16b92 100644
--- a/roms/ipxe/src/config/dhcp.h
+++ b/roms/ipxe/src/config/dhcp.h
@@ -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
diff --git a/roms/ipxe/src/config/general.h b/roms/ipxe/src/config/general.h
index a71ba726f..ee15f6bf1 100644
--- a/roms/ipxe/src/config/general.h
+++ b/roms/ipxe/src/config/general.h
@@ -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
*
*/
diff --git a/roms/ipxe/src/config/usb.h b/roms/ipxe/src/config/usb.h
index d2519d877..52e82eaad 100644
--- a/roms/ipxe/src/config/usb.h
+++ b/roms/ipxe/src/config/usb.h
@@ -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)
diff --git a/roms/ipxe/src/core/debug.c b/roms/ipxe/src/core/debug.c
index 9b2a823f5..def5d8b09 100644
--- a/roms/ipxe/src/core/debug.c
+++ b/roms/ipxe/src/core/debug.c
@@ -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" );
}
diff --git a/roms/ipxe/src/core/downloader.c b/roms/ipxe/src/core/downloader.c
index ba678f868..d745f3617 100644
--- a/roms/ipxe/src/core/downloader.c
+++ b/roms/ipxe/src/core/downloader.c
@@ -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 ),
};
diff --git a/roms/ipxe/src/core/exec.c b/roms/ipxe/src/core/exec.c
index a13884b68..2c2ade0a5 100644
--- a/roms/ipxe/src/core/exec.c
+++ b/roms/ipxe/src/core/exec.c
@@ -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;
}
diff --git a/roms/ipxe/src/core/fbcon.c b/roms/ipxe/src/core/fbcon.c
index 44a56e105..6d8b0086d 100644
--- a/roms/ipxe/src/core/fbcon.c
+++ b/roms/ipxe/src/core/fbcon.c
@@ -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 */
diff --git a/roms/ipxe/src/core/gdbstub.c b/roms/ipxe/src/core/gdbstub.c
index 8b57ddf56..6ad52d1a6 100644
--- a/roms/ipxe/src/core/gdbstub.c
+++ b/roms/ipxe/src/core/gdbstub.c
@@ -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 ) {
diff --git a/roms/ipxe/src/core/getkey.c b/roms/ipxe/src/core/getkey.c
index 0c280d23b..0f0f8b7c3 100644
--- a/roms/ipxe/src/core/getkey.c
+++ b/roms/ipxe/src/core/getkey.c
@@ -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;
diff --git a/roms/ipxe/src/core/image.c b/roms/ipxe/src/core/image.c
index a185b82f4..529e3d72c 100644
--- a/roms/ipxe/src/core/image.c
+++ b/roms/ipxe/src/core/image.c
@@ -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 ) );
diff --git a/roms/ipxe/src/core/iobuf.c b/roms/ipxe/src/core/iobuf.c
index 0ee53e038..3e52ada4f 100644
--- a/roms/ipxe/src/core/iobuf.c
+++ b/roms/ipxe/src/core/iobuf.c
@@ -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
index c7f487274..000000000
--- a/roms/ipxe/src/core/iomap_virt.c
+++ /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 );
diff --git a/roms/ipxe/src/core/malloc.c b/roms/ipxe/src/core/malloc.c
index 32c203532..b120c0325 100644
--- a/roms/ipxe/src/core/malloc.c
+++ b/roms/ipxe/src/core/malloc.c
@@ -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
index 000000000..aecddc22c
--- /dev/null
+++ b/roms/ipxe/src/core/memblock.c
@@ -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;
+}
diff --git a/roms/ipxe/src/core/memmap_settings.c b/roms/ipxe/src/core/memmap_settings.c
index 1098bd756..fab3e5f3a 100644
--- a/roms/ipxe/src/core/memmap_settings.c
+++ b/roms/ipxe/src/core/memmap_settings.c
@@ -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 ) &&
diff --git a/roms/ipxe/src/core/pixbuf.c b/roms/ipxe/src/core/pixbuf.c
index c12bd3c06..41e18f8dc 100644
--- a/roms/ipxe/src/core/pixbuf.c
+++ b/roms/ipxe/src/core/pixbuf.c
@@ -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;
diff --git a/roms/ipxe/src/core/random.c b/roms/ipxe/src/core/random.c
index 975a03cf5..a74175a79 100644
--- a/roms/ipxe/src/core/random.c
+++ b/roms/ipxe/src/core/random.c
@@ -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 */
}
/**
diff --git a/roms/ipxe/src/core/serial.c b/roms/ipxe/src/core/serial.c
index dd22f6731..4ce025519 100644
--- a/roms/ipxe/src/core/serial.c
+++ b/roms/ipxe/src/core/serial.c
@@ -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>
diff --git a/roms/ipxe/src/core/settings.c b/roms/ipxe/src/core/settings.c
index 9cae0cae3..12e6c7d61 100644
--- a/roms/ipxe/src/core/settings.c
+++ b/roms/ipxe/src/core/settings.c
@@ -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 */
diff --git a/roms/ipxe/src/core/string.c b/roms/ipxe/src/core/string.c
index 5a185e635..3e658e54e 100644
--- a/roms/ipxe/src/core/string.c
+++ b/roms/ipxe/src/core/string.c
@@ -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;
diff --git a/roms/ipxe/src/core/time.c b/roms/ipxe/src/core/time.c
index c353ac5bd..29a924ebe 100644
--- a/roms/ipxe/src/core/time.c
+++ b/roms/ipxe/src/core/time.c
@@ -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"
diff --git a/roms/ipxe/src/core/timer.c b/roms/ipxe/src/core/timer.c
index ca945cfba..dbd89f12b 100644
--- a/roms/ipxe/src/core/timer.c
+++ b/roms/ipxe/src/core/timer.c
@@ -24,10 +24,6 @@
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;
}
diff --git a/roms/ipxe/src/core/uri.c b/roms/ipxe/src/core/uri.c
index 73ad2b227..3b5f270fe 100644
--- a/roms/ipxe/src/core/uri.c
+++ b/roms/ipxe/src/core/uri.c
@@ -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 );
}
diff --git a/roms/ipxe/src/core/vsprintf.c b/roms/ipxe/src/core/vsprintf.c
index 9d3a97c2d..cb3bec5dd 100644
--- a/roms/ipxe/src/core/vsprintf.c
+++ b/roms/ipxe/src/core/vsprintf.c
@@ -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;
diff --git a/roms/ipxe/src/crypto/asn1.c b/roms/ipxe/src/crypto/asn1.c
index 9c71ffe10..aca12bf30 100644
--- a/roms/ipxe/src/crypto/asn1.c
+++ b/roms/ipxe/src/crypto/asn1.c
@@ -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
diff --git a/roms/ipxe/src/crypto/certstore.c b/roms/ipxe/src/crypto/certstore.c
index e62d8330b..503ce499e 100644
--- a/roms/ipxe/src/crypto/certstore.c
+++ b/roms/ipxe/src/crypto/certstore.c
@@ -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" \
diff --git a/roms/ipxe/src/crypto/drbg.c b/roms/ipxe/src/crypto/drbg.c
index a3366e806..5c8b5e612 100644
--- a/roms/ipxe/src/crypto/drbg.c
+++ b/roms/ipxe/src/crypto/drbg.c
@@ -19,18 +19,6 @@
* 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 );
diff --git a/roms/ipxe/src/crypto/hash_df.c b/roms/ipxe/src/crypto/hash_df.c
index dc0dc0ce8..c1417e683 100644
--- a/roms/ipxe/src/crypto/hash_df.c
+++ b/roms/ipxe/src/crypto/hash_df.c
@@ -19,18 +19,6 @@
* 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 );
diff --git a/roms/ipxe/src/crypto/hmac.c b/roms/ipxe/src/crypto/hmac.c
index f898619c8..95a46195c 100644
--- a/roms/ipxe/src/crypto/hmac.c
+++ b/roms/ipxe/src/crypto/hmac.c
@@ -19,18 +19,6 @@
* 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 );
diff --git a/roms/ipxe/src/crypto/hmac_drbg.c b/roms/ipxe/src/crypto/hmac_drbg.c
index 098297716..6c1d5deb2 100644
--- a/roms/ipxe/src/crypto/hmac_drbg.c
+++ b/roms/ipxe/src/crypto/hmac_drbg.c
@@ -19,18 +19,6 @@
* 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 );
diff --git a/roms/ipxe/src/crypto/ocsp.c b/roms/ipxe/src/crypto/ocsp.c
index e7adcdba9..5df55bc96 100644
--- a/roms/ipxe/src/crypto/ocsp.c
+++ b/roms/ipxe/src/crypto/ocsp.c
@@ -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;
}
diff --git a/roms/ipxe/src/crypto/privkey.c b/roms/ipxe/src/crypto/privkey.c
index 7ef04880f..a6043bd1e 100644
--- a/roms/ipxe/src/crypto/privkey.c
+++ b/roms/ipxe/src/crypto/privkey.c
@@ -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 );
diff --git a/roms/ipxe/src/crypto/rbg.c b/roms/ipxe/src/crypto/rbg.c
index a5a77e3cd..943b288c3 100644
--- a/roms/ipxe/src/crypto/rbg.c
+++ b/roms/ipxe/src/crypto/rbg.c
@@ -19,18 +19,6 @@
* 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 );
diff --git a/roms/ipxe/src/crypto/rootcert.c b/roms/ipxe/src/crypto/rootcert.c
index f7b9dcfb7..00ea1647e 100644
--- a/roms/ipxe/src/crypto/rootcert.c
+++ b/roms/ipxe/src/crypto/rootcert.c
@@ -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,
};
diff --git a/roms/ipxe/src/drivers/block/ibft.c b/roms/ipxe/src/drivers/block/ibft.c
index 91a808d85..6aabd766a 100644
--- a/roms/ipxe/src/drivers/block/ibft.c
+++ b/roms/ipxe/src/drivers/block/ibft.c
@@ -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,
diff --git a/roms/ipxe/src/drivers/bus/pci.c b/roms/ipxe/src/drivers/bus/pci.c
index 06b36a770..6fbedd940 100644
--- a/roms/ipxe/src/drivers/bus/pci.c
+++ b/roms/ipxe/src/drivers/bus/pci.c
@@ -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++ ) {
diff --git a/roms/ipxe/src/drivers/bus/pci_settings.c b/roms/ipxe/src/drivers/bus/pci_settings.c
index 98005559d..1cb9fa5a3 100644
--- a/roms/ipxe/src/drivers/bus/pci_settings.c
+++ b/roms/ipxe/src/drivers/bus/pci_settings.c
@@ -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
index aaa69cf4c..000000000
--- a/roms/ipxe/src/drivers/bus/pciea.c
+++ /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 );
-}
diff --git a/roms/ipxe/src/drivers/bus/pciextra.c b/roms/ipxe/src/drivers/bus/pciextra.c
index 3082d8a3d..82287fb86 100644
--- a/roms/ipxe/src/drivers/bus/pciextra.c
+++ b/roms/ipxe/src/drivers/bus/pciextra.c
@@ -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;
}
/**
diff --git a/roms/ipxe/src/drivers/bus/usb.c b/roms/ipxe/src/drivers/bus/usb.c
index 880e3f08c..2019e3341 100644
--- a/roms/ipxe/src/drivers/bus/usb.c
+++ b/roms/ipxe/src/drivers/bus/usb.c
@@ -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;
}
diff --git a/roms/ipxe/src/drivers/bus/virtio-pci.c b/roms/ipxe/src/drivers/bus/virtio-pci.c
index 3311595fb..fbef067bc 100644
--- a/roms/ipxe/src/drivers/bus/virtio-pci.c
+++ b/roms/ipxe/src/drivers/bus/virtio-pci.c
@@ -11,15 +11,10 @@
*
*/
-#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;
-}
diff --git a/roms/ipxe/src/drivers/bus/virtio-ring.c b/roms/ipxe/src/drivers/bus/virtio-ring.c
index 98e787e16..e55b6d0ed 100644
--- a/roms/ipxe/src/drivers/bus/virtio-ring.c
+++ b/roms/ipxe/src/drivers/bus/virtio-ring.c
@@ -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
index 6d07c0151..000000000
--- a/roms/ipxe/src/drivers/infiniband/CIB_PRM.h
+++ /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__ */
diff --git a/roms/ipxe/src/drivers/infiniband/arbel.c b/roms/ipxe/src/drivers/infiniband/arbel.c
index 9671174c3..2a6c32dec 100644
--- a/roms/ipxe/src/drivers/infiniband/arbel.c
+++ b/roms/ipxe/src/drivers/infiniband/arbel.c
@@ -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 );
}
diff --git a/roms/ipxe/src/drivers/infiniband/arbel.h b/roms/ipxe/src/drivers/infiniband/arbel.h
index 8a5a996a3..73394cd9a 100644
--- a/roms/ipxe/src/drivers/infiniband/arbel.h
+++ b/roms/ipxe/src/drivers/infiniband/arbel.h
@@ -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
index dea19ca69..000000000
--- a/roms/ipxe/src/drivers/infiniband/flexboot_nodnic.c
+++ /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
index 80272296c..000000000
--- a/roms/ipxe/src/drivers/infiniband/flexboot_nodnic.h
+++ /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
index d410fdfb9..000000000
--- a/roms/ipxe/src/drivers/infiniband/golan.c
+++ /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
index a6cb4e744..000000000
--- a/roms/ipxe/src/drivers/infiniband/golan.h
+++ /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_*/
diff --git a/roms/ipxe/src/drivers/infiniband/hermon.c b/roms/ipxe/src/drivers/infiniband/hermon.c
index 79d606093..a9c728706 100644
--- a/roms/ipxe/src/drivers/infiniband/hermon.c
+++ b/roms/ipxe/src/drivers/infiniband/hermon.c
@@ -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 );
}
diff --git a/roms/ipxe/src/drivers/infiniband/hermon.h b/roms/ipxe/src/drivers/infiniband/hermon.h
index 61e285781..e0b028f26 100644
--- a/roms/ipxe/src/drivers/infiniband/hermon.h
+++ b/roms/ipxe/src/drivers/infiniband/hermon.h
@@ -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;
};
diff --git a/roms/ipxe/src/drivers/infiniband/linda.c b/roms/ipxe/src/drivers/infiniband/linda.c
index 77d50d110..a6ae9f529 100644
--- a/roms/ipxe/src/drivers/infiniband/linda.c
+++ b/roms/ipxe/src/drivers/infiniband/linda.c
@@ -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 );
}
diff --git a/roms/ipxe/src/drivers/infiniband/linda.h b/roms/ipxe/src/drivers/infiniband/linda.h
index 44c7686f4..46a920a17 100644
--- a/roms/ipxe/src/drivers/infiniband/linda.h
+++ b/roms/ipxe/src/drivers/infiniband/linda.h
@@ -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
index e1e89b4c3..000000000
--- a/roms/ipxe/src/drivers/infiniband/mlx_nodnic/include/mlx_cmd.h
+++ /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
index b0cc7f723..000000000
--- a/roms/ipxe/src/drivers/infiniband/mlx_nodnic/include/mlx_device.h
+++ /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
index f58213b98..000000000
--- a/roms/ipxe/src/drivers/infiniband/mlx_nodnic/include/mlx_nodnic_data_structures.h
+++ /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
index 4fd96a6da..000000000
--- a/roms/ipxe/src/drivers/infiniband/mlx_nodnic/include/mlx_port.h
+++ /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
index 69f85358b..000000000
--- a/roms/ipxe/src/drivers/infiniband/mlx_nodnic/src/mlx_cmd.c
+++ /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
index 4acc94fa6..000000000
--- a/roms/ipxe/src/drivers/infiniband/mlx_nodnic/src/mlx_device.c
+++ /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
index a7afdab65..000000000
--- a/roms/ipxe/src/drivers/infiniband/mlx_nodnic/src/mlx_port.c
+++ /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
index 1f8ba89ea..000000000
--- a/roms/ipxe/src/drivers/infiniband/mlx_utils/include/private/mlx_memory_priv.h
+++ /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
index 89cad75eb..000000000
--- a/roms/ipxe/src/drivers/infiniband/mlx_utils/include/private/mlx_pci_priv.h
+++ /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
index 268b76fad..000000000
--- a/roms/ipxe/src/drivers/infiniband/mlx_utils/include/private/mlx_utils_priv.h
+++ /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
index a4f4b37b1..000000000
--- a/roms/ipxe/src/drivers/infiniband/mlx_utils/include/public/mlx_bail.h
+++ /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
index 1ed423daf..000000000
--- a/roms/ipxe/src/drivers/infiniband/mlx_utils/include/public/mlx_icmd.h
+++ /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
index 7b7b852d1..000000000
--- a/roms/ipxe/src/drivers/infiniband/mlx_utils/include/public/mlx_logging.h
+++ /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
index 056756666..000000000
--- a/roms/ipxe/src/drivers/infiniband/mlx_utils/include/public/mlx_memory.h
+++ /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
index 416bdb66b..000000000
--- a/roms/ipxe/src/drivers/infiniband/mlx_utils/include/public/mlx_pci.h
+++ /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
index c074a22e5..000000000
--- a/roms/ipxe/src/drivers/infiniband/mlx_utils/include/public/mlx_pci_gw.h
+++ /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
index 9c66567a3..000000000
--- a/roms/ipxe/src/drivers/infiniband/mlx_utils/include/public/mlx_types.h
+++ /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
index 46ad97c3b..000000000
--- a/roms/ipxe/src/drivers/infiniband/mlx_utils/include/public/mlx_utils.h
+++ /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
index ba56e72f2..000000000
--- a/roms/ipxe/src/drivers/infiniband/mlx_utils/mlx_lib/mlx_blink_leds/mlx_blink_leds.c
+++ /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
index 886645fe2..000000000
--- a/roms/ipxe/src/drivers/infiniband/mlx_utils/mlx_lib/mlx_blink_leds/mlx_blink_leds.h
+++ /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
index d31553024..000000000
--- a/roms/ipxe/src/drivers/infiniband/mlx_utils/mlx_lib/mlx_link_speed/mlx_link_speed.c
+++ /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
index 15b28f57a..000000000
--- a/roms/ipxe/src/drivers/infiniband/mlx_utils/mlx_lib/mlx_link_speed/mlx_link_speed.h
+++ /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
index 755730284..000000000
--- a/roms/ipxe/src/drivers/infiniband/mlx_utils/mlx_lib/mlx_mtu/mlx_mtu.c
+++ /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
index c6222625c..000000000
--- a/roms/ipxe/src/drivers/infiniband/mlx_utils/mlx_lib/mlx_mtu/mlx_mtu.h
+++ /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
index 2277e0c76..000000000
--- a/roms/ipxe/src/drivers/infiniband/mlx_utils/mlx_lib/mlx_nvconfig/mlx_nvconfig.c
+++ /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
index 8333e8368..000000000
--- a/roms/ipxe/src/drivers/infiniband/mlx_utils/mlx_lib/mlx_nvconfig/mlx_nvconfig.h
+++ /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
index 77eda8a5c..000000000
--- a/roms/ipxe/src/drivers/infiniband/mlx_utils/mlx_lib/mlx_nvconfig/mlx_nvconfig_defaults.c
+++ /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
index 163c2a35f..000000000
--- a/roms/ipxe/src/drivers/infiniband/mlx_utils/mlx_lib/mlx_nvconfig/mlx_nvconfig_defaults.h
+++ /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
index 5b3af1e78..000000000
--- a/roms/ipxe/src/drivers/infiniband/mlx_utils/mlx_lib/mlx_nvconfig/mlx_nvconfig_prm.h
+++ /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
index 3852efbf1..000000000
--- a/roms/ipxe/src/drivers/infiniband/mlx_utils/mlx_lib/mlx_ocbb/mlx_ocbb.c
+++ /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
index 49312b98f..000000000
--- a/roms/ipxe/src/drivers/infiniband/mlx_utils/mlx_lib/mlx_ocbb/mlx_ocbb.h
+++ /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
index 143ab1b0e..000000000
--- a/roms/ipxe/src/drivers/infiniband/mlx_utils/mlx_lib/mlx_reg_access/mlx_reg_access.c
+++ /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
index 9fbf51631..000000000
--- a/roms/ipxe/src/drivers/infiniband/mlx_utils/mlx_lib/mlx_reg_access/mlx_reg_access.h
+++ /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
index 65d04c967..000000000
--- a/roms/ipxe/src/drivers/infiniband/mlx_utils/mlx_lib/mlx_vmac/mlx_vmac.c
+++ /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
index 2214d9189..000000000
--- a/roms/ipxe/src/drivers/infiniband/mlx_utils/mlx_lib/mlx_vmac/mlx_vmac.h
+++ /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
index a6c23c4a1..000000000
--- a/roms/ipxe/src/drivers/infiniband/mlx_utils/mlx_lib/mlx_wol_rol/mlx_wol_rol.c
+++ /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
index 610419d5d..000000000
--- a/roms/ipxe/src/drivers/infiniband/mlx_utils/mlx_lib/mlx_wol_rol/mlx_wol_rol.h
+++ /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
index 4386ad9b9..000000000
--- a/roms/ipxe/src/drivers/infiniband/mlx_utils/src/private/uefi/mlx_logging_impl.c
+++ /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
index f7d365dee..000000000
--- a/roms/ipxe/src/drivers/infiniband/mlx_utils/src/public/mlx_icmd.c
+++ /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
index 5aa5a53d2..000000000
--- a/roms/ipxe/src/drivers/infiniband/mlx_utils/src/public/mlx_memory.c
+++ /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
index 91c44d991..000000000
--- a/roms/ipxe/src/drivers/infiniband/mlx_utils/src/public/mlx_pci.c
+++ /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
index 30c1e644e..000000000
--- a/roms/ipxe/src/drivers/infiniband/mlx_utils/src/public/mlx_pci_gw.c
+++ /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
index c824b17e9..000000000
--- a/roms/ipxe/src/drivers/infiniband/mlx_utils/src/public/mlx_utils.c
+++ /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
index af7e86f44..000000000
--- a/roms/ipxe/src/drivers/infiniband/mlx_utils_flexboot/include/mlx_logging_priv.h
+++ /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
index feaeae679..000000000
--- a/roms/ipxe/src/drivers/infiniband/mlx_utils_flexboot/include/mlx_types_priv.h
+++ /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
index cb9e759bf..000000000
--- a/roms/ipxe/src/drivers/infiniband/mlx_utils_flexboot/src/mlx_memory_priv.c
+++ /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
index f8caefdce..000000000
--- a/roms/ipxe/src/drivers/infiniband/mlx_utils_flexboot/src/mlx_pci_priv.c
+++ /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
index 5fca406fc..000000000
--- a/roms/ipxe/src/drivers/infiniband/mlx_utils_flexboot/src/mlx_utils_priv.c
+++ /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
index 5e0fa9890..000000000
--- a/roms/ipxe/src/drivers/infiniband/nodnic_prm.h
+++ /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
index 85cd97187..000000000
--- a/roms/ipxe/src/drivers/infiniband/nodnic_shomron_prm.h
+++ /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_ */
diff --git a/roms/ipxe/src/drivers/infiniband/qib7322.c b/roms/ipxe/src/drivers/infiniband/qib7322.c
index af7006e04..e22f2349a 100644
--- a/roms/ipxe/src/drivers/infiniband/qib7322.c
+++ b/roms/ipxe/src/drivers/infiniband/qib7322.c
@@ -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 );
}
diff --git a/roms/ipxe/src/drivers/infiniband/qib7322.h b/roms/ipxe/src/drivers/infiniband/qib7322.h
index dab95cfc0..72797b240 100644
--- a/roms/ipxe/src/drivers/infiniband/qib7322.h
+++ b/roms/ipxe/src/drivers/infiniband/qib7322.h
@@ -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 */
diff --git a/roms/ipxe/src/drivers/net/3c595.c b/roms/ipxe/src/drivers/net/3c595.c
index 92d38cfc5..2338c54b7 100644
--- a/roms/ipxe/src/drivers/net/3c595.c
+++ b/roms/ipxe/src/drivers/net/3c595.c
@@ -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;
diff --git a/roms/ipxe/src/drivers/net/3c5x9.c b/roms/ipxe/src/drivers/net/3c5x9.c
index d7c09f77c..4d9bc8d9e 100644
--- a/roms/ipxe/src/drivers/net/3c5x9.c
+++ b/roms/ipxe/src/drivers/net/3c5x9.c
@@ -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
index 16dab4be8..000000000
--- a/roms/ipxe/src/drivers/net/acm.c
+++ /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
index d4944967b..000000000
--- a/roms/ipxe/src/drivers/net/acm.h
+++ /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 */
diff --git a/roms/ipxe/src/drivers/net/ath/ath.h b/roms/ipxe/src/drivers/net/ath/ath.h
index d6a037394..42ad59f78 100644
--- a/roms/ipxe/src/drivers/net/ath/ath.h
+++ b/roms/ipxe/src/drivers/net/ath/ath.h
@@ -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);
diff --git a/roms/ipxe/src/drivers/net/ath/ath5k/ath5k.c b/roms/ipxe/src/drivers/net/ath/ath5k/ath5k.c
index a6a65a2e9..92c4ffdf4 100644
--- a/roms/ipxe/src/drivers/net/ath/ath5k/ath5k.c
+++ b/roms/ipxe/src/drivers/net/ath/ath5k/ath5k.c
@@ -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
diff --git a/roms/ipxe/src/drivers/net/ath/ath5k/ath5k_phy.c b/roms/ipxe/src/drivers/net/ath/ath5k/ath5k_phy.c
index c2a66a4d3..7891d39ea 100644
--- a/roms/ipxe/src/drivers/net/ath/ath5k/ath5k_phy.c
+++ b/roms/ipxe/src/drivers/net/ath/ath5k/ath5k_phy.c
@@ -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)) |
diff --git a/roms/ipxe/src/drivers/net/ath/ath5k/ath5k_reset.c b/roms/ipxe/src/drivers/net/ath/ath5k/ath5k_reset.c
index 73765a7b0..2f36a4e9a 100644
--- a/roms/ipxe/src/drivers/net/ath/ath5k/ath5k_reset.c
+++ b/roms/ipxe/src/drivers/net/ath/ath5k/ath5k_reset.c
@@ -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
*
diff --git a/roms/ipxe/src/drivers/net/ath/ath9k/ar9002_initvals.h b/roms/ipxe/src/drivers/net/ath/ath9k/ar9002_initvals.h
index f9a92c9b7..d7a5ac09f 100644
--- a/roms/ipxe/src/drivers/net/ath/ath9k/ar9002_initvals.h
+++ b/roms/ipxe/src/drivers/net/ath/ath9k/ar9002_initvals.h
@@ -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},
diff --git a/roms/ipxe/src/drivers/net/ath/ath9k/ar9003_2p2_initvals.h b/roms/ipxe/src/drivers/net/ath/ath9k/ar9003_2p2_initvals.h
index b1303bbaa..e8ac70da5 100644
--- a/roms/ipxe/src/drivers/net/ath/ath9k/ar9003_2p2_initvals.h
+++ b/roms/ipxe/src/drivers/net/ath/ath9k/ar9003_2p2_initvals.h
@@ -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},
diff --git a/roms/ipxe/src/drivers/net/ath/ath9k/ar9340_initvals.h b/roms/ipxe/src/drivers/net/ath/ath9k/ar9340_initvals.h
index 784080b16..815a8af1b 100644
--- a/roms/ipxe/src/drivers/net/ath/ath9k/ar9340_initvals.h
+++ b/roms/ipxe/src/drivers/net/ath/ath9k/ar9340_initvals.h
@@ -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},
diff --git a/roms/ipxe/src/drivers/net/ath/ath9k/ar9485_initvals.h b/roms/ipxe/src/drivers/net/ath/ath9k/ar9485_initvals.h
index c854398aa..611ea6ce8 100644
--- a/roms/ipxe/src/drivers/net/ath/ath9k/ar9485_initvals.h
+++ b/roms/ipxe/src/drivers/net/ath/ath9k/ar9485_initvals.h
@@ -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},
diff --git a/roms/ipxe/src/drivers/net/ath/ath9k/ath9k_eeprom.c b/roms/ipxe/src/drivers/net/ath/ath9k/ath9k_eeprom.c
index a20423790..f552acaa3 100644
--- a/roms/ipxe/src/drivers/net/ath/ath9k/ath9k_eeprom.c
+++ b/roms/ipxe/src/drivers/net/ath/ath9k/ath9k_eeprom.c
@@ -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],
diff --git a/roms/ipxe/src/drivers/net/ath/ath9k/ath9k_init.c b/roms/ipxe/src/drivers/net/ath/ath9k/ath9k_init.c
index 98a0d6d59..03de7701a 100644
--- a/roms/ipxe/src/drivers/net/ath/ath9k/ath9k_init.c
+++ b/roms/ipxe/src/drivers/net/ath/ath9k/ath9k_init.c
@@ -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,
diff --git a/roms/ipxe/src/drivers/net/ath/ath9k/ath9k_recv.c b/roms/ipxe/src/drivers/net/ath/ath9k/ath9k_recv.c
index 0ffe9d45a..ba363c676 100644
--- a/roms/ipxe/src/drivers/net/ath/ath9k/ath9k_recv.c
+++ b/roms/ipxe/src/drivers/net/ath/ath9k/ath9k_recv.c
@@ -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
index 000000000..85d159a36
--- /dev/null
+++ b/roms/ipxe/src/drivers/net/ath/ath_main.c
@@ -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
index ab59a8be7..000000000
--- a/roms/ipxe/src/drivers/net/axge.c
+++ /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
index 65bf911c5..000000000
--- a/roms/ipxe/src/drivers/net/axge.h
+++ /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 */
diff --git a/roms/ipxe/src/drivers/net/dm96xx.c b/roms/ipxe/src/drivers/net/dm96xx.c
index 61b957be9..58d8dd964 100644
--- a/roms/ipxe/src/drivers/net/dm96xx.c
+++ b/roms/ipxe/src/drivers/net/dm96xx.c
@@ -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,
};
diff --git a/roms/ipxe/src/drivers/net/ecm.c b/roms/ipxe/src/drivers/net/ecm.c
index f2d9161c1..8c84ea9e9 100644
--- a/roms/ipxe/src/drivers/net/ecm.c
+++ b/roms/ipxe/src/drivers/net/ecm.c
@@ -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,
};
diff --git a/roms/ipxe/src/drivers/net/efi/nii.c b/roms/ipxe/src/drivers/net/efi/nii.c
index d68b36cc3..b91848f5c 100644
--- a/roms/ipxe/src/drivers/net/efi/nii.c
+++ b/roms/ipxe/src/drivers/net/efi/nii.c
@@ -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 )
diff --git a/roms/ipxe/src/drivers/net/efi/snp.c b/roms/ipxe/src/drivers/net/efi/snp.c
index fbd606902..acfcfba9f 100644
--- a/roms/ipxe/src/drivers/net/efi/snp.c
+++ b/roms/ipxe/src/drivers/net/efi/snp.c
@@ -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;
}
diff --git a/roms/ipxe/src/drivers/net/efi/snpnet.c b/roms/ipxe/src/drivers/net/efi/snpnet.c
index 88474b0be..96642c4ca 100644
--- a/roms/ipxe/src/drivers/net/efi/snpnet.c
+++ b/roms/ipxe/src/drivers/net/efi/snpnet.c
@@ -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 */
}
diff --git a/roms/ipxe/src/drivers/net/efi/snponly.c b/roms/ipxe/src/drivers/net/efi/snponly.c
index cb7ea1bbc..73abfdbf4 100644
--- a/roms/ipxe/src/drivers/net/efi/snponly.c
+++ b/roms/ipxe/src/drivers/net/efi/snponly.c
@@ -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
index f58e74b7d..000000000
--- a/roms/ipxe/src/drivers/net/eoib.c
+++ /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;
- }
-}
diff --git a/roms/ipxe/src/drivers/net/etherfabric.c b/roms/ipxe/src/drivers/net/etherfabric.c
index 2cd41d4ca..29d117443 100644
--- a/roms/ipxe/src/drivers/net/etherfabric.c
+++ b/roms/ipxe/src/drivers/net/etherfabric.c
@@ -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" );
diff --git a/roms/ipxe/src/drivers/net/intel.c b/roms/ipxe/src/drivers/net/intel.c
index 127f5c7e7..6309e9aa5 100644
--- a/roms/ipxe/src/drivers/net/intel.c
+++ b/roms/ipxe/src/drivers/net/intel.c
@@ -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 ),
};
diff --git a/roms/ipxe/src/drivers/net/intel.h b/roms/ipxe/src/drivers/net/intel.h
index 16a72a11b..ce9e3f467 100644
--- a/roms/ipxe/src/drivers/net/intel.h
+++ b/roms/ipxe/src/drivers/net/intel.h
@@ -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,
};
/**
diff --git a/roms/ipxe/src/drivers/net/ipoib.c b/roms/ipxe/src/drivers/net/ipoib.c
index 8a65c87ba..6552d764e 100644
--- a/roms/ipxe/src/drivers/net/ipoib.c
+++ b/roms/ipxe/src/drivers/net/ipoib.c
@@ -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;
-}
diff --git a/roms/ipxe/src/drivers/net/ncm.c b/roms/ipxe/src/drivers/net/ncm.c
index 1837291f7..10728d2a1 100644
--- a/roms/ipxe/src/drivers/net/ncm.c
+++ b/roms/ipxe/src/drivers/net/ncm.c
@@ -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,
};
diff --git a/roms/ipxe/src/drivers/net/ncm.h b/roms/ipxe/src/drivers/net/ncm.h
index 6b0d21cdb..a9565a56b 100644
--- a/roms/ipxe/src/drivers/net/ncm.h
+++ b/roms/ipxe/src/drivers/net/ncm.h
@@ -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 | \
diff --git a/roms/ipxe/src/drivers/net/phantom/phantom.c b/roms/ipxe/src/drivers/net/phantom/phantom.c
index 781049ff4..38b66743c 100644
--- a/roms/ipxe/src/drivers/net/phantom/phantom.c
+++ b/roms/ipxe/src/drivers/net/phantom/phantom.c
@@ -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 */
diff --git a/roms/ipxe/src/drivers/net/sis190.c b/roms/ipxe/src/drivers/net/sis190.c
index 81f3d9844..991c30f9e 100644
--- a/roms/ipxe/src/drivers/net/sis190.c
+++ b/roms/ipxe/src/drivers/net/sis190.c
@@ -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;
diff --git a/roms/ipxe/src/drivers/net/sis190.h b/roms/ipxe/src/drivers/net/sis190.h
index 79f94d2d9..0551333d5 100644
--- a/roms/ipxe/src/drivers/net/sis190.h
+++ b/roms/ipxe/src/drivers/net/sis190.h
@@ -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);
diff --git a/roms/ipxe/src/drivers/net/skge.c b/roms/ipxe/src/drivers/net/skge.c
index c3264225b..6384e7647 100755
--- a/roms/ipxe/src/drivers/net/skge.c
+++ b/roms/ipxe/src/drivers/net/skge.c
@@ -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)
diff --git a/roms/ipxe/src/drivers/net/smsc75xx.c b/roms/ipxe/src/drivers/net/smsc75xx.c
index 4ce98ac80..017e02a59 100644
--- a/roms/ipxe/src/drivers/net/smsc75xx.c
+++ b/roms/ipxe/src/drivers/net/smsc75xx.c
@@ -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,
};
diff --git a/roms/ipxe/src/drivers/net/smsc75xx.h b/roms/ipxe/src/drivers/net/smsc75xx.h
index ae81fc168..2463b72a1 100644
--- a/roms/ipxe/src/drivers/net/smsc75xx.h
+++ b/roms/ipxe/src/drivers/net/smsc75xx.h
@@ -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
index 3d9c0f1aa..000000000
--- a/roms/ipxe/src/drivers/net/smsc95xx.c
+++ /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
index c2512e0ee..000000000
--- a/roms/ipxe/src/drivers/net/smsc95xx.h
+++ /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 */
diff --git a/roms/ipxe/src/drivers/net/tg3/tg3.c b/roms/ipxe/src/drivers/net/tg3/tg3.c
index 1bed06649..42bfa2d99 100644
--- a/roms/ipxe/src/drivers/net/tg3/tg3.c
+++ b/roms/ipxe/src/drivers/net/tg3/tg3.c
@@ -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;
diff --git a/roms/ipxe/src/drivers/net/tg3/tg3.h b/roms/ipxe/src/drivers/net/tg3/tg3.h
index be02c5719..2b85b065b 100644
--- a/roms/ipxe/src/drivers/net/tg3/tg3.h
+++ b/roms/ipxe/src/drivers/net/tg3/tg3.h
@@ -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
index 306adc459..000000000
--- a/roms/ipxe/src/drivers/net/thunderx.c
+++ /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
index 410daf6e2..000000000
--- a/roms/ipxe/src/drivers/net/thunderx.h
+++ /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
index 235c54319..000000000
--- a/roms/ipxe/src/drivers/net/thunderxcfg.h
+++ /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 */
diff --git a/roms/ipxe/src/drivers/net/virtio-net.c b/roms/ipxe/src/drivers/net/virtio-net.c
index fe0fd4b86..533ccb0c6 100644
--- a/roms/ipxe/src/drivers/net/virtio-net.c
+++ b/roms/ipxe/src/drivers/net/virtio-net.c
@@ -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 = {
diff --git a/roms/ipxe/src/drivers/net/virtio-net.h b/roms/ipxe/src/drivers/net/virtio-net.h
index c2b4a17cc..3abef28ea 100644
--- a/roms/ipxe/src/drivers/net/virtio-net.h
+++ b/roms/ipxe/src/drivers/net/virtio-net.h
@@ -14,12 +14,6 @@
#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_ */
diff --git a/roms/ipxe/src/drivers/net/vmxnet3.c b/roms/ipxe/src/drivers/net/vmxnet3.c
index 6a54dbf89..8d4f4b843 100644
--- a/roms/ipxe/src/drivers/net/vmxnet3.c
+++ b/roms/ipxe/src/drivers/net/vmxnet3.c
@@ -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++;
diff --git a/roms/ipxe/src/drivers/net/vmxnet3.h b/roms/ipxe/src/drivers/net/vmxnet3.h
index 5e1e0cb6e..a1671d9dd 100644
--- a/roms/ipxe/src/drivers/net/vmxnet3.h
+++ b/roms/ipxe/src/drivers/net/vmxnet3.h
@@ -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
diff --git a/roms/ipxe/src/drivers/usb/ehci.c b/roms/ipxe/src/drivers/usb/ehci.c
index 35cbc8de9..4124692a6 100644
--- a/roms/ipxe/src/drivers/usb/ehci.c
+++ b/roms/ipxe/src/drivers/usb/ehci.c
@@ -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;
diff --git a/roms/ipxe/src/drivers/usb/uhci.c b/roms/ipxe/src/drivers/usb/uhci.c
index 528c1be1d..b6bb92560 100644
--- a/roms/ipxe/src/drivers/usb/uhci.c
+++ b/roms/ipxe/src/drivers/usb/uhci.c
@@ -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 */
diff --git a/roms/ipxe/src/drivers/usb/usbhub.c b/roms/ipxe/src/drivers/usb/usbhub.c
index 47914bcdb..bf2a20005 100644
--- a/roms/ipxe/src/drivers/usb/usbhub.c
+++ b/roms/ipxe/src/drivers/usb/usbhub.c
@@ -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,
};
diff --git a/roms/ipxe/src/drivers/usb/usbhub.h b/roms/ipxe/src/drivers/usb/usbhub.h
index a5f123acc..d7d8f9610 100644
--- a/roms/ipxe/src/drivers/usb/usbhub.h
+++ b/roms/ipxe/src/drivers/usb/usbhub.h
@@ -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
index 153f39421..000000000
--- a/roms/ipxe/src/drivers/usb/usbio.c
+++ /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
index 1d02876f6..000000000
--- a/roms/ipxe/src/drivers/usb/usbio.h
+++ /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 */
diff --git a/roms/ipxe/src/drivers/usb/usbkbd.c b/roms/ipxe/src/drivers/usb/usbkbd.c
index a8ab6ab76..ea94f2e63 100644
--- a/roms/ipxe/src/drivers/usb/usbkbd.c
+++ b/roms/ipxe/src/drivers/usb/usbkbd.c
@@ -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 */
diff --git a/roms/ipxe/src/drivers/usb/usbkbd.h b/roms/ipxe/src/drivers/usb/usbkbd.h
index cedebfe71..7eab24e46 100644
--- a/roms/ipxe/src/drivers/usb/usbkbd.h
+++ b/roms/ipxe/src/drivers/usb/usbkbd.h
@@ -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.
diff --git a/roms/ipxe/src/drivers/usb/usbnet.c b/roms/ipxe/src/drivers/usb/usbnet.c
index d18d81772..b92336d05 100644
--- a/roms/ipxe/src/drivers/usb/usbnet.c
+++ b/roms/ipxe/src/drivers/usb/usbnet.c
@@ -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];
diff --git a/roms/ipxe/src/drivers/usb/xhci.c b/roms/ipxe/src/drivers/usb/xhci.c
index 48ac6a307..49e67316b 100644
--- a/roms/ipxe/src/drivers/usb/xhci.c
+++ b/roms/ipxe/src/drivers/usb/xhci.c
@@ -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
index 1154d749e..000000000
--- a/roms/ipxe/src/hci/commands/ibmgmt_cmd.c
+++ /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,
- },
-};
diff --git a/roms/ipxe/src/hci/commands/lotest_cmd.c b/roms/ipxe/src/hci/commands/lotest_cmd.c
index 393b3c36e..a989932d4 100644
--- a/roms/ipxe/src/hci/commands/lotest_cmd.c
+++ b/roms/ipxe/src/hci/commands/lotest_cmd.c
@@ -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
index 8f741a512..000000000
--- a/roms/ipxe/src/hci/commands/ntp_cmd.c
+++ /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,
-};
diff --git a/roms/ipxe/src/hci/mucurses/windows.c b/roms/ipxe/src/hci/mucurses/windows.c
index 5f5d1f4e2..7f39bdea2 100644
--- a/roms/ipxe/src/hci/mucurses/windows.c
+++ b/roms/ipxe/src/hci/mucurses/windows.c
@@ -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 );
diff --git a/roms/ipxe/src/image/efi_image.c b/roms/ipxe/src/image/efi_image.c
index 47580c0db..b7d8f9c6e 100644
--- a/roms/ipxe/src/image/efi_image.c
+++ b/roms/ipxe/src/image/efi_image.c
@@ -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:
diff --git a/roms/ipxe/src/image/embedded.c b/roms/ipxe/src/image/embedded.c
index 376e5d299..48dd86851 100644
--- a/roms/ipxe/src/image/embedded.c
+++ b/roms/ipxe/src/image/embedded.c
@@ -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" \
diff --git a/roms/ipxe/src/include/compiler.h b/roms/ipxe/src/include/compiler.h
index 32afb64cf..ca82f9523 100644
--- a/roms/ipxe/src/include/compiler.h
+++ b/roms/ipxe/src/include/compiler.h
@@ -52,17 +52,6 @@
/** 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: ; \
@@ -150,14 +139,14 @@
*/
#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" \
diff --git a/roms/ipxe/src/include/errno.h b/roms/ipxe/src/include/errno.h
index 342384fa4..036479aff 100644
--- a/roms/ipxe/src/include/errno.h
+++ b/roms/ipxe/src/include/errno.h
@@ -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" \
diff --git a/roms/ipxe/src/include/ipxe/asn1.h b/roms/ipxe/src/include/ipxe/asn1.h
index 2e635b48a..5fbd58281 100644
--- a/roms/ipxe/src/include/ipxe/asn1.h
+++ b/roms/ipxe/src/include/ipxe/asn1.h
@@ -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 );
diff --git a/roms/ipxe/src/include/ipxe/bitops.h b/roms/ipxe/src/include/ipxe/bitops.h
index 7366cd9f1..220ab0fe7 100644
--- a/roms/ipxe/src/include/ipxe/bitops.h
+++ b/roms/ipxe/src/include/ipxe/bitops.h
@@ -1,19 +1,235 @@
#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 */
diff --git a/roms/ipxe/src/include/ipxe/cdc.h b/roms/ipxe/src/include/ipxe/cdc.h
index b8b4a59d9..f1799cd9a 100644
--- a/roms/ipxe/src/include/ipxe/cdc.h
+++ b/roms/ipxe/src/include/ipxe/cdc.h
@@ -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 */
diff --git a/roms/ipxe/src/include/ipxe/dhcp.h b/roms/ipxe/src/include/ipxe/dhcp.h
index 693aa7e73..a11db3497 100644
--- a/roms/ipxe/src/include/ipxe/dhcp.h
+++ b/roms/ipxe/src/include/ipxe/dhcp.h
@@ -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
index d4301726f..000000000
--- a/roms/ipxe/src/include/ipxe/efi/AArch64/ProcessorBind.h
+++ /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
index 51a727145..000000000
--- a/roms/ipxe/src/include/ipxe/efi/Arm/ProcessorBind.h
+++ /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
-
-
diff --git a/roms/ipxe/src/include/ipxe/efi/Base.h b/roms/ipxe/src/include/ipxe/efi/Base.h
index 8a047aef0..844f428f1 100644
--- a/roms/ipxe/src/include/ipxe/efi/Base.h
+++ b/roms/ipxe/src/include/ipxe/efi/Base.h
@@ -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
diff --git a/roms/ipxe/src/include/ipxe/efi/Guid/SmBios.h b/roms/ipxe/src/include/ipxe/efi/Guid/SmBios.h
index 49142897a..cc4a1f946 100644
--- a/roms/ipxe/src/include/ipxe/efi/Guid/SmBios.h
+++ b/roms/ipxe/src/include/ipxe/efi/Guid/SmBios.h
@@ -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
diff --git a/roms/ipxe/src/include/ipxe/efi/Ia32/ProcessorBind.h b/roms/ipxe/src/include/ipxe/efi/Ia32/ProcessorBind.h
index 375ff2d92..16e30b358 100644
--- a/roms/ipxe/src/include/ipxe/efi/Ia32/ProcessorBind.h
+++ b/roms/ipxe/src/include/ipxe/efi/Ia32/ProcessorBind.h
@@ -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
index f5ff44c9c..000000000
--- a/roms/ipxe/src/include/ipxe/efi/IndustryStandard/Acpi20.h
+++ /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
index abaa72128..000000000
--- a/roms/ipxe/src/include/ipxe/efi/IndustryStandard/Acpi30.h
+++ /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
index 5fcad3e42..000000000
--- a/roms/ipxe/src/include/ipxe/efi/IndustryStandard/Acpi40.h
+++ /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
index df9e71531..000000000
--- a/roms/ipxe/src/include/ipxe/efi/IndustryStandard/Acpi50.h
+++ /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
index b00613942..000000000
--- a/roms/ipxe/src/include/ipxe/efi/IndustryStandard/Acpi51.h
+++ /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
index 18eb5f7d9..000000000
--- a/roms/ipxe/src/include/ipxe/efi/IndustryStandard/Acpi60.h
+++ /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
index f63ab8901..000000000
--- a/roms/ipxe/src/include/ipxe/efi/IndustryStandard/Bluetooth.h
+++ /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
diff --git a/roms/ipxe/src/include/ipxe/efi/IndustryStandard/Pci22.h b/roms/ipxe/src/include/ipxe/efi/IndustryStandard/Pci22.h
index f0f2ae922..a73820f69 100644
--- a/roms/ipxe/src/include/ipxe/efi/IndustryStandard/Pci22.h
+++ b/roms/ipxe/src/include/ipxe/efi/IndustryStandard/Pci22.h
@@ -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
index 656bf21eb..000000000
--- a/roms/ipxe/src/include/ipxe/efi/IndustryStandard/Tpm20.h
+++ /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
diff --git a/roms/ipxe/src/include/ipxe/efi/IndustryStandard/UefiTcgPlatform.h b/roms/ipxe/src/include/ipxe/efi/IndustryStandard/UefiTcgPlatform.h
index df65be914..8bb7ea389 100644
--- a/roms/ipxe/src/include/ipxe/efi/IndustryStandard/UefiTcgPlatform.h
+++ b/roms/ipxe/src/include/ipxe/efi/IndustryStandard/UefiTcgPlatform.h
@@ -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
@@ -18,14 +18,12 @@
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
index 7eb1a8d95..000000000
--- a/roms/ipxe/src/include/ipxe/efi/IndustryStandard/Usb.h
+++ /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
diff --git a/roms/ipxe/src/include/ipxe/efi/Library/BaseLib.h b/roms/ipxe/src/include/ipxe/efi/Library/BaseLib.h
index a45a20d70..e9c31d130 100644
--- a/roms/ipxe/src/include/ipxe/efi/Library/BaseLib.h
+++ b/roms/ipxe/src/include/ipxe/efi/Library/BaseLib.h
@@ -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
diff --git a/roms/ipxe/src/include/ipxe/efi/Pi/PiDxeCis.h b/roms/ipxe/src/include/ipxe/efi/Pi/PiDxeCis.h
index 047c077c4..50d25f23f 100644
--- a/roms/ipxe/src/include/ipxe/efi/Pi/PiDxeCis.h
+++ b/roms/ipxe/src/include/ipxe/efi/Pi/PiDxeCis.h
@@ -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
diff --git a/roms/ipxe/src/include/ipxe/efi/Pi/PiFirmwareFile.h b/roms/ipxe/src/include/ipxe/efi/Pi/PiFirmwareFile.h
index 9bd22a544..f6cf9574d 100644
--- a/roms/ipxe/src/include/ipxe/efi/Pi/PiFirmwareFile.h
+++ b/roms/ipxe/src/include/ipxe/efi/Pi/PiFirmwareFile.h
@@ -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;
diff --git a/roms/ipxe/src/include/ipxe/efi/Pi/PiHob.h b/roms/ipxe/src/include/ipxe/efi/Pi/PiHob.h
index 121748dec..c68ea3002 100644
--- a/roms/ipxe/src/include/ipxe/efi/Pi/PiHob.h
+++ b/roms/ipxe/src/include/ipxe/efi/Pi/PiHob.h
@@ -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,
diff --git a/roms/ipxe/src/include/ipxe/efi/Pi/PiMultiPhase.h b/roms/ipxe/src/include/ipxe/efi/Pi/PiMultiPhase.h
index f35bb14cf..daf6591f5 100644
--- a/roms/ipxe/src/include/ipxe/efi/Pi/PiMultiPhase.h
+++ b/roms/ipxe/src/include/ipxe/efi/Pi/PiMultiPhase.h
@@ -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
diff --git a/roms/ipxe/src/include/ipxe/efi/ProcessorBind.h b/roms/ipxe/src/include/ipxe/efi/ProcessorBind.h
index ff1517f33..7466814fa 100644
--- a/roms/ipxe/src/include/ipxe/efi/ProcessorBind.h
+++ b/roms/ipxe/src/include/ipxe/efi/ProcessorBind.h
@@ -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
index b20ca0574..000000000
--- a/roms/ipxe/src/include/ipxe/efi/Protocol/AbsolutePointer.h
+++ /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
index 144beff1c..000000000
--- a/roms/ipxe/src/include/ipxe/efi/Protocol/AppleNetBoot.h
+++ /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
index 000000000..665924e88
--- /dev/null
+++ b/roms/ipxe/src/include/ipxe/efi/Protocol/Cpu.h
@@ -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
diff --git a/roms/ipxe/src/include/ipxe/efi/Protocol/DevicePath.h b/roms/ipxe/src/include/ipxe/efi/Protocol/DevicePath.h
index d35b65fa9..a305df575 100644
--- a/roms/ipxe/src/include/ipxe/efi/Protocol/DevicePath.h
+++ b/roms/ipxe/src/include/ipxe/efi/Protocol/DevicePath.h
@@ -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;
diff --git a/roms/ipxe/src/include/ipxe/efi/Protocol/FormBrowser2.h b/roms/ipxe/src/include/ipxe/efi/Protocol/FormBrowser2.h
index 8033a11d3..0c0f56d73 100644
--- a/roms/ipxe/src/include/ipxe/efi/Protocol/FormBrowser2.h
+++ b/roms/ipxe/src/include/ipxe/efi/Protocol/FormBrowser2.h
@@ -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
/**
diff --git a/roms/ipxe/src/include/ipxe/efi/Protocol/HiiConfigAccess.h b/roms/ipxe/src/include/ipxe/efi/Protocol/HiiConfigAccess.h
index df9080591..17ce3fdcc 100644
--- a/roms/ipxe/src/include/ipxe/efi/Protocol/HiiConfigAccess.h
+++ b/roms/ipxe/src/include/ipxe/efi/Protocol/HiiConfigAccess.h
@@ -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
index f2b72dc11..000000000
--- a/roms/ipxe/src/include/ipxe/efi/Protocol/HiiFont.h
+++ /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
index b18d51a61..000000000
--- a/roms/ipxe/src/include/ipxe/efi/Protocol/HiiImage.h
+++ /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
-
-
diff --git a/roms/ipxe/src/include/ipxe/efi/Protocol/LoadFile.h b/roms/ipxe/src/include/ipxe/efi/Protocol/LoadFile.h
index ba80fdc16..99387e89f 100644
--- a/roms/ipxe/src/include/ipxe/efi/Protocol/LoadFile.h
+++ b/roms/ipxe/src/include/ipxe/efi/Protocol/LoadFile.h
@@ -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
index 130a6ecdc..000000000
--- a/roms/ipxe/src/include/ipxe/efi/Protocol/SerialIo.h
+++ /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
diff --git a/roms/ipxe/src/include/ipxe/efi/Protocol/SimpleNetwork.h b/roms/ipxe/src/include/ipxe/efi/Protocol/SimpleNetwork.h
index 2faa668f3..2b521a9de 100644
--- a/roms/ipxe/src/include/ipxe/efi/Protocol/SimpleNetwork.h
+++ b/roms/ipxe/src/include/ipxe/efi/Protocol/SimpleNetwork.h
@@ -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
index 3b1e3057b..000000000
--- a/roms/ipxe/src/include/ipxe/efi/Protocol/SimplePointer.h
+++ /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
diff --git a/roms/ipxe/src/include/ipxe/efi/Protocol/SimpleTextOut.h b/roms/ipxe/src/include/ipxe/efi/Protocol/SimpleTextOut.h
index 8aa36c35a..a79cf431c 100644
--- a/roms/ipxe/src/include/ipxe/efi/Protocol/SimpleTextOut.h
+++ b/roms/ipxe/src/include/ipxe/efi/Protocol/SimpleTextOut.h
@@ -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
diff --git a/roms/ipxe/src/include/ipxe/efi/Protocol/TcgService.h b/roms/ipxe/src/include/ipxe/efi/Protocol/TcgService.h
index 86c69a84e..1068448f0 100644
--- a/roms/ipxe/src/include/ipxe/efi/Protocol/TcgService.h
+++ b/roms/ipxe/src/include/ipxe/efi/Protocol/TcgService.h
@@ -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
index 565020688..000000000
--- a/roms/ipxe/src/include/ipxe/efi/Protocol/UgaDraw.h
+++ /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
index 870428c2b..000000000
--- a/roms/ipxe/src/include/ipxe/efi/Protocol/UnicodeCollation.h
+++ /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
index 8308e8f1b..000000000
--- a/roms/ipxe/src/include/ipxe/efi/Protocol/Usb2HostController.h
+++ /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
index a29088c6f..000000000
--- a/roms/ipxe/src/include/ipxe/efi/Protocol/UsbHostController.h
+++ /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
index b8d33ee0c..000000000
--- a/roms/ipxe/src/include/ipxe/efi/Protocol/UsbIo.h
+++ /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
diff --git a/roms/ipxe/src/include/ipxe/efi/Uefi/UefiBaseType.h b/roms/ipxe/src/include/ipxe/efi/Uefi/UefiBaseType.h
index ef0ea671a..371dae649 100644
--- a/roms/ipxe/src/include/ipxe/efi/Uefi/UefiBaseType.h
+++ b/roms/ipxe/src/include/ipxe/efi/Uefi/UefiBaseType.h
@@ -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
///@}
///
diff --git a/roms/ipxe/src/include/ipxe/efi/Uefi/UefiInternalFormRepresentation.h b/roms/ipxe/src/include/ipxe/efi/Uefi/UefiInternalFormRepresentation.h
index 49ea24ff9..19121dea7 100644
--- a/roms/ipxe/src/include/ipxe/efi/Uefi/UefiInternalFormRepresentation.h
+++ b/roms/ipxe/src/include/ipxe/efi/Uefi/UefiInternalFormRepresentation.h
@@ -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;
diff --git a/roms/ipxe/src/include/ipxe/efi/Uefi/UefiMultiPhase.h b/roms/ipxe/src/include/ipxe/efi/Uefi/UefiMultiPhase.h
index 38ec09f3d..678f3ebd6 100644
--- a/roms/ipxe/src/include/ipxe/efi/Uefi/UefiMultiPhase.h
+++ b/roms/ipxe/src/include/ipxe/efi/Uefi/UefiMultiPhase.h
@@ -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 {
diff --git a/roms/ipxe/src/include/ipxe/efi/Uefi/UefiPxe.h b/roms/ipxe/src/include/ipxe/efi/Uefi/UefiPxe.h
index 13be21aae..5c0b2038f 100644
--- a/roms/ipxe/src/include/ipxe/efi/Uefi/UefiPxe.h
+++ b/roms/ipxe/src/include/ipxe/efi/Uefi/UefiPxe.h
@@ -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.
diff --git a/roms/ipxe/src/include/ipxe/efi/Uefi/UefiSpec.h b/roms/ipxe/src/include/ipxe/efi/Uefi/UefiSpec.h
index 98ac8765f..422b2f30e 100644
--- a/roms/ipxe/src/include/ipxe/efi/Uefi/UefiSpec.h
+++ b/roms/ipxe/src/include/ipxe/efi/Uefi/UefiSpec.h
@@ -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
diff --git a/roms/ipxe/src/include/ipxe/efi/X64/ProcessorBind.h b/roms/ipxe/src/include/ipxe/efi/X64/ProcessorBind.h
index b64c25c0f..4f21bb8de 100644
--- a/roms/ipxe/src/include/ipxe/efi/X64/ProcessorBind.h
+++ b/roms/ipxe/src/include/ipxe/efi/X64/ProcessorBind.h
@@ -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
diff --git a/roms/ipxe/src/include/ipxe/efi/efi.h b/roms/ipxe/src/include/ipxe/efi/efi.h
index db9943a42..ab52dd9e0 100644
--- a/roms/ipxe/src/include/ipxe/efi/efi.h
+++ b/roms/ipxe/src/include/ipxe/efi/efi.h
@@ -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 );
diff --git a/roms/ipxe/src/include/ipxe/efi/efi_driver.h b/roms/ipxe/src/include/ipxe/efi/efi_driver.h
index 74ece90db..f497df3e3 100644
--- a/roms/ipxe/src/include/ipxe/efi/efi_driver.h
+++ b/roms/ipxe/src/include/ipxe/efi/efi_driver.h
@@ -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
index b356f3789..000000000
--- a/roms/ipxe/src/include/ipxe/efi/efi_pxe.h
+++ /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 */
diff --git a/roms/ipxe/src/include/ipxe/efi/efi_snp.h b/roms/ipxe/src/include/ipxe/efi/efi_snp.h
index 4c5461ec4..1e5c66626 100644
--- a/roms/ipxe/src/include/ipxe/efi/efi_snp.h
+++ b/roms/ipxe/src/include/ipxe/efi/efi_snp.h
@@ -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 */
diff --git a/roms/ipxe/src/include/ipxe/efi/efi_timer.h b/roms/ipxe/src/include/ipxe/efi/efi_timer.h
index c49875988..c03765393 100644
--- a/roms/ipxe/src/include/ipxe/efi/efi_timer.h
+++ b/roms/ipxe/src/include/ipxe/efi/efi_timer.h
@@ -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
index 05b4fad00..000000000
--- a/roms/ipxe/src/include/ipxe/efi/efi_usb.h
+++ /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 */
diff --git a/roms/ipxe/src/include/ipxe/efi/efi_utils.h b/roms/ipxe/src/include/ipxe/efi/efi_utils.h
index 67acba17e..57268daf7 100644
--- a/roms/ipxe/src/include/ipxe/efi/efi_utils.h
+++ b/roms/ipxe/src/include/ipxe/efi/efi_utils.h
@@ -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
index 93f496c36..000000000
--- a/roms/ipxe/src/include/ipxe/eoib.h
+++ /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 */
diff --git a/roms/ipxe/src/include/ipxe/errfile.h b/roms/ipxe/src/include/ipxe/errfile.h
index f743dae6f..e21c95938 100644
--- a/roms/ipxe/src/include/ipxe/errfile.h
+++ b/roms/ipxe/src/include/ipxe/errfile.h
@@ -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 )
/** @} */
diff --git a/roms/ipxe/src/include/ipxe/fbcon.h b/roms/ipxe/src/include/ipxe/fbcon.h
index 42ffca3d7..d442bb918 100644
--- a/roms/ipxe/src/include/ipxe/fbcon.h
+++ b/roms/ipxe/src/include/ipxe/fbcon.h
@@ -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 );
diff --git a/roms/ipxe/src/include/ipxe/ib_cmrc.h b/roms/ipxe/src/include/ipxe/ib_cmrc.h
index f3276e6ef..47ad27fa6 100644
--- a/roms/ipxe/src/include/ipxe/ib_cmrc.h
+++ b/roms/ipxe/src/include/ipxe/ib_cmrc.h
@@ -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 */
diff --git a/roms/ipxe/src/include/ipxe/ib_mad.h b/roms/ipxe/src/include/ipxe/ib_mad.h
index 134274026..ae1eea7e4 100644
--- a/roms/ipxe/src/include/ipxe/ib_mad.h
+++ b/roms/ipxe/src/include/ipxe/ib_mad.h
@@ -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;
diff --git a/roms/ipxe/src/include/ipxe/ib_mcast.h b/roms/ipxe/src/include/ipxe/ib_mcast.h
index df348bd9b..564066975 100644
--- a/roms/ipxe/src/include/ipxe/ib_mcast.h
+++ b/roms/ipxe/src/include/ipxe/ib_mcast.h
@@ -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 );
diff --git a/roms/ipxe/src/include/ipxe/ib_packet.h b/roms/ipxe/src/include/ipxe/ib_packet.h
index 747f96399..f275fcb09 100644
--- a/roms/ipxe/src/include/ipxe/ib_packet.h
+++ b/roms/ipxe/src/include/ipxe/ib_packet.h
@@ -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
index 88afe4e65..000000000
--- a/roms/ipxe/src/include/ipxe/ib_service.h
+++ /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 */
diff --git a/roms/ipxe/src/include/ipxe/if_arp.h b/roms/ipxe/src/include/ipxe/if_arp.h
index 9d7b03fe8..4eb1f80b7 100644
--- a/roms/ipxe/src/include/ipxe/if_arp.h
+++ b/roms/ipxe/src/include/ipxe/if_arp.h
@@ -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 */
diff --git a/roms/ipxe/src/include/ipxe/image.h b/roms/ipxe/src/include/ipxe/image.h
index f33feddad..6abd7a2d2 100644
--- a/roms/ipxe/src/include/ipxe/image.h
+++ b/roms/ipxe/src/include/ipxe/image.h
@@ -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 );
diff --git a/roms/ipxe/src/include/ipxe/infiniband.h b/roms/ipxe/src/include/ipxe/infiniband.h
index d7ecd1623..87cfe5082 100644
--- a/roms/ipxe/src/include/ipxe/infiniband.h
+++ b/roms/ipxe/src/include/ipxe/infiniband.h
@@ -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 */
diff --git a/roms/ipxe/src/include/ipxe/io.h b/roms/ipxe/src/include/ipxe/io.h
index fe1388191..af767915d 100644
--- a/roms/ipxe/src/include/ipxe/io.h
+++ b/roms/ipxe/src/include/ipxe/io.h
@@ -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
index b8ded38ef..000000000
--- a/roms/ipxe/src/include/ipxe/iomap.h
+++ /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
index 4962b7c37..000000000
--- a/roms/ipxe/src/include/ipxe/iomap_virt.h
+++ /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 */
diff --git a/roms/ipxe/src/include/ipxe/ipoib.h b/roms/ipxe/src/include/ipxe/ipoib.h
index 065eeabb7..b34dd32d0 100644
--- a/roms/ipxe/src/include/ipxe/ipoib.h
+++ b/roms/ipxe/src/include/ipxe/ipoib.h
@@ -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
index 000000000..4704c4817
--- /dev/null
+++ b/roms/ipxe/src/include/ipxe/linux_compat.h
@@ -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
index f5b3d2326..000000000
--- a/roms/ipxe/src/include/ipxe/ntp.h
+++ /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 */
diff --git a/roms/ipxe/src/include/ipxe/pci.h b/roms/ipxe/src/include/ipxe/pci.h
index ddd8c8d1e..a841e00ff 100644
--- a/roms/ipxe/src/include/ipxe/pci.h
+++ b/roms/ipxe/src/include/ipxe/pci.h
@@ -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
index 941c94ed5..000000000
--- a/roms/ipxe/src/include/ipxe/pciea.h
+++ /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 */
diff --git a/roms/ipxe/src/include/ipxe/pool.h b/roms/ipxe/src/include/ipxe/pool.h
index 81ff57d75..27066e9b3 100644
--- a/roms/ipxe/src/include/ipxe/pool.h
+++ b/roms/ipxe/src/include/ipxe/pool.h
@@ -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
index 431b106fa..000000000
--- a/roms/ipxe/src/include/ipxe/pseudobit.h
+++ /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 */
diff --git a/roms/ipxe/src/include/ipxe/sanboot.h b/roms/ipxe/src/include/ipxe/sanboot.h
index 041e18935..57025f2c6 100644
--- a/roms/ipxe/src/include/ipxe/sanboot.h
+++ b/roms/ipxe/src/include/ipxe/sanboot.h
@@ -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 );
diff --git a/roms/ipxe/src/include/ipxe/settings.h b/roms/ipxe/src/include/ipxe/settings.h
index 6534c25b6..95a553cc8 100644
--- a/roms/ipxe/src/include/ipxe/settings.h
+++ b/roms/ipxe/src/include/ipxe/settings.h
@@ -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
diff --git a/roms/ipxe/src/include/ipxe/smbios.h b/roms/ipxe/src/include/ipxe/smbios.h
index c1d8fea3e..24b05ed62 100644
--- a/roms/ipxe/src/include/ipxe/smbios.h
+++ b/roms/ipxe/src/include/ipxe/smbios.h
@@ -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
*
diff --git a/roms/ipxe/src/include/ipxe/tcp.h b/roms/ipxe/src/include/ipxe/tcp.h
index 21be3ca8a..063ebaa4b 100644
--- a/roms/ipxe/src/include/ipxe/tcp.h
+++ b/roms/ipxe/src/include/ipxe/tcp.h
@@ -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
*
*/
diff --git a/roms/ipxe/src/include/ipxe/tcpip.h b/roms/ipxe/src/include/ipxe/tcpip.h
index 414daad53..3cfc8e3ac 100644
--- a/roms/ipxe/src/include/ipxe/tcpip.h
+++ b/roms/ipxe/src/include/ipxe/tcpip.h
@@ -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 */
diff --git a/roms/ipxe/src/include/ipxe/time.h b/roms/ipxe/src/include/ipxe/time.h
index 89bf90e03..4c5bb2a00 100644
--- a/roms/ipxe/src/include/ipxe/time.h
+++ b/roms/ipxe/src/include/ipxe/time.h
@@ -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 */
diff --git a/roms/ipxe/src/include/ipxe/uri.h b/roms/ipxe/src/include/ipxe/uri.h
index 3879a0e73..00e5a24c4 100644
--- a/roms/ipxe/src/include/ipxe/uri.h
+++ b/roms/ipxe/src/include/ipxe/uri.h
@@ -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 */
diff --git a/roms/ipxe/src/include/ipxe/usb.h b/roms/ipxe/src/include/ipxe/usb.h
index e7909d300..ab060b8f4 100644
--- a/roms/ipxe/src/include/ipxe/usb.h
+++ b/roms/ipxe/src/include/ipxe/usb.h
@@ -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 */
diff --git a/roms/ipxe/src/include/ipxe/usbhid.h b/roms/ipxe/src/include/ipxe/usbhid.h
index 233534e0f..fe9d84455 100644
--- a/roms/ipxe/src/include/ipxe/usbhid.h
+++ b/roms/ipxe/src/include/ipxe/usbhid.h
@@ -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 );
diff --git a/roms/ipxe/src/include/ipxe/virtio-pci.h b/roms/ipxe/src/include/ipxe/virtio-pci.h
index f3c9b17ca..a09c46316 100644
--- a/roms/ipxe/src/include/ipxe/virtio-pci.h
+++ b/roms/ipxe/src/include/ipxe/virtio-pci.h
@@ -37,104 +37,6 @@
/* 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_ */
diff --git a/roms/ipxe/src/include/ipxe/virtio-ring.h b/roms/ipxe/src/include/ipxe/virtio-ring.h
index 6ba550b5a..c687acab7 100644
--- a/roms/ipxe/src/include/ipxe/virtio-ring.h
+++ b/roms/ipxe/src/include/ipxe/virtio-ring.h
@@ -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_ */
diff --git a/roms/ipxe/src/include/ipxe/xen.h b/roms/ipxe/src/include/ipxe/xen.h
index 0fb8b7625..eac1145ad 100644
--- a/roms/ipxe/src/include/ipxe/xen.h
+++ b/roms/ipxe/src/include/ipxe/xen.h
@@ -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
index f4f14c487..000000000
--- a/roms/ipxe/src/include/ipxe/xsigo.h
+++ /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 */
diff --git a/roms/ipxe/src/include/nic.h b/roms/ipxe/src/include/nic.h
index 8b06e88f4..4c91f57a6 100644
--- a/roms/ipxe/src/include/nic.h
+++ b/roms/ipxe/src/include/nic.h
@@ -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 ); \
diff --git a/roms/ipxe/src/include/stddef.h b/roms/ipxe/src/include/stddef.h
index fb01c489d..3c056294f 100644
--- a/roms/ipxe/src/include/stddef.h
+++ b/roms/ipxe/src/include/stddef.h
@@ -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; } )
diff --git a/roms/ipxe/src/include/string.h b/roms/ipxe/src/include/string.h
index 0f4182001..0fab6c74b 100644
--- a/roms/ipxe/src/include/string.h
+++ b/roms/ipxe/src/include/string.h
@@ -10,14 +10,6 @@
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;
diff --git a/roms/ipxe/src/include/time.h b/roms/ipxe/src/include/time.h
index ab93a3dbb..462ac6999 100644
--- a/roms/ipxe/src/include/time.h
+++ b/roms/ipxe/src/include/time.h
@@ -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
index 16a099134..000000000
--- a/roms/ipxe/src/include/usr/ibmgmt.h
+++ /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 */
diff --git a/roms/ipxe/src/include/usr/lotest.h b/roms/ipxe/src/include/usr/lotest.h
index bd66f4a44..ce0fe5eda 100644
--- a/roms/ipxe/src/include/usr/lotest.h
+++ b/roms/ipxe/src/include/usr/lotest.h
@@ -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
index 284e668e6..000000000
--- a/roms/ipxe/src/include/usr/ntpmgmt.h
+++ /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 */
diff --git a/roms/ipxe/src/interface/bofm/bofm.c b/roms/ipxe/src/interface/bofm/bofm.c
index 54039193a..545088dc6 100644
--- a/roms/ipxe/src/interface/bofm/bofm.c
+++ b/roms/ipxe/src/interface/bofm/bofm.c
@@ -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;
diff --git a/roms/ipxe/src/interface/efi/efi_bofm.c b/roms/ipxe/src/interface/efi/efi_bofm.c
index 00f6a1d5c..ea0e15f7f 100644
--- a/roms/ipxe/src/interface/efi/efi_bofm.c
+++ b/roms/ipxe/src/interface/efi/efi_bofm.c
@@ -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;
}
}
diff --git a/roms/ipxe/src/interface/efi/efi_console.c b/roms/ipxe/src/interface/efi/efi_console.c
index 047baed47..3b30f3097 100644
--- a/roms/ipxe/src/interface/efi/efi_console.c
+++ b/roms/ipxe/src/interface/efi/efi_console.c
@@ -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
diff --git a/roms/ipxe/src/interface/efi/efi_debug.c b/roms/ipxe/src/interface/efi/efi_debug.c
index 19531fdc1..473803951 100644
--- a/roms/ipxe/src/interface/efi/efi_debug.c
+++ b/roms/ipxe/src/interface/efi/efi_debug.c
@@ -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";
}
diff --git a/roms/ipxe/src/interface/efi/efi_driver.c b/roms/ipxe/src/interface/efi/efi_driver.c
index 22aa3ee72..ba7784cd7 100644
--- a/roms/ipxe/src/interface/efi/efi_driver.c
+++ b/roms/ipxe/src/interface/efi/efi_driver.c
@@ -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
index abc5a9390..000000000
--- a/roms/ipxe/src/interface/efi/efi_fbcon.c
+++ /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,
-};
diff --git a/roms/ipxe/src/interface/efi/efi_file.c b/roms/ipxe/src/interface/efi/efi_file.c
index 52de0987c..3715b70bf 100644
--- a/roms/ipxe/src/interface/efi/efi_file.c
+++ b/roms/ipxe/src/interface/efi/efi_file.c
@@ -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
diff --git a/roms/ipxe/src/interface/efi/efi_guid.c b/roms/ipxe/src/interface/efi/efi_guid.c
index 62ee5a517..ab1c91e9f 100644
--- a/roms/ipxe/src/interface/efi/efi_guid.c
+++ b/roms/ipxe/src/interface/efi/efi_guid.c
@@ -24,14 +24,11 @@
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
index bd010ad2e..000000000
--- a/roms/ipxe/src/interface/efi/efi_local.c
+++ /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,
-};
diff --git a/roms/ipxe/src/interface/efi/efi_pci.c b/roms/ipxe/src/interface/efi/efi_pci.c
index 9f0851a56..97ea72bb9 100644
--- a/roms/ipxe/src/interface/efi/efi_pci.c
+++ b/roms/ipxe/src/interface/efi/efi_pci.c
@@ -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
index a1f81df59..000000000
--- a/roms/ipxe/src/interface/efi/efi_pxe.c
+++ /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 );
-}
diff --git a/roms/ipxe/src/interface/efi/efi_snp.c b/roms/ipxe/src/interface/efi/efi_snp.c
index e6388bf67..3dfcc5e16 100644
--- a/roms/ipxe/src/interface/efi/efi_snp.c
+++ b/roms/ipxe/src/interface/efi/efi_snp.c
@@ -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 )
diff --git a/roms/ipxe/src/interface/efi/efi_snp_hii.c b/roms/ipxe/src/interface/efi/efi_snp_hii.c
index 1e87ea15a..720402bdb 100644
--- a/roms/ipxe/src/interface/efi/efi_snp_hii.c
+++ b/roms/ipxe/src/interface/efi/efi_snp_hii.c
@@ -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 ) {
diff --git a/roms/ipxe/src/interface/efi/efi_timer.c b/roms/ipxe/src/interface/efi/efi_timer.c
index da064120a..81620c92c 100644
--- a/roms/ipxe/src/interface/efi/efi_timer.c
+++ b/roms/ipxe/src/interface/efi/efi_timer.c
@@ -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
index db8c3d348..000000000
--- a/roms/ipxe/src/interface/efi/efi_usb.c
+++ /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,
-};
diff --git a/roms/ipxe/src/interface/efi/efi_utils.c b/roms/ipxe/src/interface/efi/efi_utils.c
index 4dc75414c..936ad48ec 100644
--- a/roms/ipxe/src/interface/efi/efi_utils.c
+++ b/roms/ipxe/src/interface/efi/efi_utils.c
@@ -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 );
}
diff --git a/roms/ipxe/src/interface/efi/efi_wrap.c b/roms/ipxe/src/interface/efi/efi_wrap.c
index c0c40eec6..2ea184e97 100644
--- a/roms/ipxe/src/interface/efi/efi_wrap.c
+++ b/roms/ipxe/src/interface/efi/efi_wrap.c
@@ -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,
diff --git a/roms/ipxe/src/interface/hyperv/vmbus.c b/roms/ipxe/src/interface/hyperv/vmbus.c
index fd809dda4..795929eae 100644
--- a/roms/ipxe/src/interface/hyperv/vmbus.c
+++ b/roms/ipxe/src/interface/hyperv/vmbus.c
@@ -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 );
diff --git a/roms/ipxe/src/interface/smbios/smbios_settings.c b/roms/ipxe/src/interface/smbios/smbios_settings.c
index 2d571f2e4..5eadfa081 100644
--- a/roms/ipxe/src/interface/smbios/smbios_settings.c
+++ b/roms/ipxe/src/interface/smbios/smbios_settings.c
@@ -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,
diff --git a/roms/ipxe/src/libgcc/__divdi3.c b/roms/ipxe/src/libgcc/__divdi3.c
index 224bb69c7..7097b11e1 100644
--- a/roms/ipxe/src/libgcc/__divdi3.c
+++ b/roms/ipxe/src/libgcc/__divdi3.c
@@ -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
index 95e328d06..000000000
--- a/roms/ipxe/src/libgcc/__divmoddi4.c
+++ /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;
-}
diff --git a/roms/ipxe/src/libgcc/__moddi3.c b/roms/ipxe/src/libgcc/__moddi3.c
index ea6fd6f7b..d671bbc4d 100644
--- a/roms/ipxe/src/libgcc/__moddi3.c
+++ b/roms/ipxe/src/libgcc/__moddi3.c
@@ -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
index 645ae6d22..000000000
--- a/roms/ipxe/src/libgcc/implicit.c
+++ /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 );
-}
diff --git a/roms/ipxe/src/libgcc/libgcc.h b/roms/ipxe/src/libgcc/libgcc.h
index eb7c68ec5..d3e9bdd73 100644
--- a/roms/ipxe/src/libgcc/libgcc.h
+++ b/roms/ipxe/src/libgcc/libgcc.h
@@ -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
index 000000000..e98b78384
--- /dev/null
+++ b/roms/ipxe/src/libgcc/memcpy.c
@@ -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 );
+}
diff --git a/roms/ipxe/src/net/arp.c b/roms/ipxe/src/net/arp.c
index c9b4109a9..1e27c44e7 100644
--- a/roms/ipxe/src/net/arp.c
+++ b/roms/ipxe/src/net/arp.c
@@ -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 ) {
diff --git a/roms/ipxe/src/net/ethernet.c b/roms/ipxe/src/net/ethernet.c
index 26fdedea8..6ddf05344 100644
--- a/roms/ipxe/src/net/ethernet.c
+++ b/roms/ipxe/src/net/ethernet.c
@@ -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 );
diff --git a/roms/ipxe/src/net/fakedhcp.c b/roms/ipxe/src/net/fakedhcp.c
index 009b12c56..b6c456a59 100644
--- a/roms/ipxe/src/net/fakedhcp.c
+++ b/roms/ipxe/src/net/fakedhcp.c
@@ -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 ) ) {
diff --git a/roms/ipxe/src/net/infiniband.c b/roms/ipxe/src/net/infiniband.c
index 15ff0529b..2e3d76d54 100644
--- a/roms/ipxe/src/net/infiniband.c
+++ b/roms/ipxe/src/net/infiniband.c
@@ -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 );
diff --git a/roms/ipxe/src/net/infiniband/ib_cm.c b/roms/ipxe/src/net/infiniband/ib_cm.c
index 247b8e7a0..85982f09d 100644
--- a/roms/ipxe/src/net/infiniband/ib_cm.c
+++ b/roms/ipxe/src/net/infiniband/ib_cm.c
@@ -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;
diff --git a/roms/ipxe/src/net/infiniband/ib_cmrc.c b/roms/ipxe/src/net/infiniband/ib_cmrc.c
index 2cd49018f..1cc0fcfef 100644
--- a/roms/ipxe/src/net/infiniband/ib_cmrc.c
+++ b/roms/ipxe/src/net/infiniband/ib_cmrc.c
@@ -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.
diff --git a/roms/ipxe/src/net/infiniband/ib_mcast.c b/roms/ipxe/src/net/infiniband/ib_mcast.c
index f7264287c..fc4ff7f0a 100644
--- a/roms/ipxe/src/net/infiniband/ib_mcast.c
+++ b/roms/ipxe/src/net/infiniband/ib_mcast.c
@@ -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 ) );
}
}
diff --git a/roms/ipxe/src/net/infiniband/ib_mi.c b/roms/ipxe/src/net/infiniband/ib_mi.c
index 548a1c829..b43212974 100644
--- a/roms/ipxe/src/net/infiniband/ib_mi.c
+++ b/roms/ipxe/src/net/infiniband/ib_mi.c
@@ -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 );
}
diff --git a/roms/ipxe/src/net/infiniband/ib_packet.c b/roms/ipxe/src/net/infiniband/ib_packet.c
index 8169925f1..d3a22d309 100644
--- a/roms/ipxe/src/net/infiniband/ib_packet.c
+++ b/roms/ipxe/src/net/infiniband/ib_packet.c
@@ -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 ) ) ),
diff --git a/roms/ipxe/src/net/infiniband/ib_pathrec.c b/roms/ipxe/src/net/infiniband/ib_pathrec.c
index f846710f2..f9cbab87f 100644
--- a/roms/ipxe/src/net/infiniband/ib_pathrec.c
+++ b/roms/ipxe/src/net/infiniband/ib_pathrec.c
@@ -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
index f035382ee..000000000
--- a/roms/ipxe/src/net/infiniband/ib_service.c
+++ /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 );
-}
diff --git a/roms/ipxe/src/net/infiniband/ib_sma.c b/roms/ipxe/src/net/infiniband/ib_sma.c
index 24ec9f4e0..a05d7c924 100644
--- a/roms/ipxe/src/net/infiniband/ib_sma.c
+++ b/roms/ipxe/src/net/infiniband/ib_sma.c
@@ -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;
}
diff --git a/roms/ipxe/src/net/infiniband/ib_smc.c b/roms/ipxe/src/net/infiniband/ib_smc.c
index 5de7deba2..c1741b26c 100644
--- a/roms/ipxe/src/net/infiniband/ib_smc.c
+++ b/roms/ipxe/src/net/infiniband/ib_smc.c
@@ -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;
}
diff --git a/roms/ipxe/src/net/infiniband/ib_srp.c b/roms/ipxe/src/net/infiniband/ib_srp.c
index 3b4914abf..3700184c0 100644
--- a/roms/ipxe/src/net/infiniband/ib_srp.c
+++ b/roms/ipxe/src/net/infiniband/ib_srp.c
@@ -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
index 91b7b71f1..000000000
--- a/roms/ipxe/src/net/infiniband/xsigo.c
+++ /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,
-};
diff --git a/roms/ipxe/src/net/ipv4.c b/roms/ipxe/src/net/ipv4.c
index 8eb04a65f..a54784049 100644
--- a/roms/ipxe/src/net/ipv4.c
+++ b/roms/ipxe/src/net/ipv4.c
@@ -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,
};
diff --git a/roms/ipxe/src/net/ipv6.c b/roms/ipxe/src/net/ipv6.c
index bbc00d33e..a75e72ddb 100644
--- a/roms/ipxe/src/net/ipv6.c
+++ b/roms/ipxe/src/net/ipv6.c
@@ -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,
};
diff --git a/roms/ipxe/src/net/netdev_settings.c b/roms/ipxe/src/net/netdev_settings.c
index 7d893a126..edd4c4b9f 100644
--- a/roms/ipxe/src/net/netdev_settings.c
+++ b/roms/ipxe/src/net/netdev_settings.c
@@ -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 },
};
/**
diff --git a/roms/ipxe/src/net/netdevice.c b/roms/ipxe/src/net/netdevice.c
index 9df21196c..7c40a2ac8 100644
--- a/roms/ipxe/src/net/netdevice.c
+++ b/roms/ipxe/src/net/netdevice.c
@@ -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;
}
diff --git a/roms/ipxe/src/net/peerblk.c b/roms/ipxe/src/net/peerblk.c
index 9fd52b736..fd7ea0893 100644
--- a/roms/ipxe/src/net/peerblk.c
+++ b/roms/ipxe/src/net/peerblk.c
@@ -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,
diff --git a/roms/ipxe/src/net/stp.c b/roms/ipxe/src/net/stp.c
index defdaed9e..d4e65a1a2 100644
--- a/roms/ipxe/src/net/stp.c
+++ b/roms/ipxe/src/net/stp.c
@@ -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" )
/**
diff --git a/roms/ipxe/src/net/tcp.c b/roms/ipxe/src/net/tcp.c
index 37a202ef1..c69c83b85 100644
--- a/roms/ipxe/src/net/tcp.c
+++ b/roms/ipxe/src/net/tcp.c
@@ -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 );
diff --git a/roms/ipxe/src/net/tcp/httpconn.c b/roms/ipxe/src/net/tcp/httpconn.c
index a2c01a418..7e4877b7b 100644
--- a/roms/ipxe/src/net/tcp/httpconn.c
+++ b/roms/ipxe/src/net/tcp/httpconn.c
@@ -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;
diff --git a/roms/ipxe/src/net/tcp/httpcore.c b/roms/ipxe/src/net/tcp/httpcore.c
index b1f74bc4f..af3ca9780 100644
--- a/roms/ipxe/src/net/tcp/httpcore.c
+++ b/roms/ipxe/src/net/tcp/httpcore.c
@@ -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;
diff --git a/roms/ipxe/src/net/tcpip.c b/roms/ipxe/src/net/tcpip.c
index c9e4ee789..5ad982fd1 100644
--- a/roms/ipxe/src/net/tcpip.c
+++ b/roms/ipxe/src/net/tcpip.c
@@ -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;
diff --git a/roms/ipxe/src/net/tls.c b/roms/ipxe/src/net/tls.c
index 90f9f9767..db01fb291 100644
--- a/roms/ipxe/src/net/tls.c
+++ b/roms/ipxe/src/net/tls.c
@@ -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;
diff --git a/roms/ipxe/src/net/udp.c b/roms/ipxe/src/net/udp.c
index 1fbc12d48..0f7dfb24a 100644
--- a/roms/ipxe/src/net/udp.c
+++ b/roms/ipxe/src/net/udp.c
@@ -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,
};
diff --git a/roms/ipxe/src/net/udp/dhcp.c b/roms/ipxe/src/net/udp/dhcp.c
index 9342ad21e..aed5ee360 100644
--- a/roms/ipxe/src/net/udp/dhcp.c
+++ b/roms/ipxe/src/net/udp/dhcp.c
@@ -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
index 11f8ccc00..000000000
--- a/roms/ipxe/src/net/udp/ntp.c
+++ /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;
-}
diff --git a/roms/ipxe/src/net/udp/slam.c b/roms/ipxe/src/net/udp/slam.c
index 8fcc97632..8b26bfb3c 100644
--- a/roms/ipxe/src/net/udp/slam.c
+++ b/roms/ipxe/src/net/udp/slam.c
@@ -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 );
diff --git a/roms/ipxe/src/net/udp/tftp.c b/roms/ipxe/src/net/udp/tftp.c
index 4255472ee..953bcb46a 100644
--- a/roms/ipxe/src/net/udp/tftp.c
+++ b/roms/ipxe/src/net/udp/tftp.c
@@ -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;
diff --git a/roms/ipxe/src/net/validator.c b/roms/ipxe/src/net/validator.c
index 57ad0e7b6..db968398a 100644
--- a/roms/ipxe/src/net/validator.c
+++ b/roms/ipxe/src/net/validator.c
@@ -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
index f29fc6801..000000000
--- a/roms/ipxe/src/tests/bitops_test.c
+++ /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,
-};
diff --git a/roms/ipxe/src/arch/x86/tests/comboot/shuffle-simple.asm b/roms/ipxe/src/tests/comboot/shuffle-simple.asm
index fa574bd72..efc7d9b46 100644
--- a/roms/ipxe/src/arch/x86/tests/comboot/shuffle-simple.asm
+++ b/roms/ipxe/src/tests/comboot/shuffle-simple.asm
@@ -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/arch/x86/tests/comboot/version.asm b/roms/ipxe/src/tests/comboot/version.asm
index 011404239..011404239 100644
--- a/roms/ipxe/src/arch/x86/tests/comboot/version.asm
+++ b/roms/ipxe/src/tests/comboot/version.asm
diff --git a/roms/ipxe/src/arch/i386/tests/gdbstub_test.S b/roms/ipxe/src/tests/gdbstub_test.S
index 739b0527a..739b0527a 100644
--- a/roms/ipxe/src/arch/i386/tests/gdbstub_test.S
+++ b/roms/ipxe/src/tests/gdbstub_test.S
diff --git a/roms/ipxe/src/arch/i386/tests/gdbstub_test.gdb b/roms/ipxe/src/tests/gdbstub_test.gdb
index bcfa07dae..bcfa07dae 100755
--- a/roms/ipxe/src/arch/i386/tests/gdbstub_test.gdb
+++ b/roms/ipxe/src/tests/gdbstub_test.gdb
diff --git a/roms/ipxe/src/tests/iobuf_test.c b/roms/ipxe/src/tests/iobuf_test.c
deleted file mode 100644
index a417c2e8c..000000000
--- a/roms/ipxe/src/tests/iobuf_test.c
+++ /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,
-};
diff --git a/roms/ipxe/src/tests/rsa_test.c b/roms/ipxe/src/tests/rsa_test.c
index 91066faab..c0d05d263 100644
--- a/roms/ipxe/src/tests/rsa_test.c
+++ b/roms/ipxe/src/tests/rsa_test.c
@@ -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>
diff --git a/roms/ipxe/src/tests/settings_test.c b/roms/ipxe/src/tests/settings_test.c
index 828901b06..f7fb35d0d 100644
--- a/roms/ipxe/src/tests/settings_test.c
+++ b/roms/ipxe/src/tests/settings_test.c
@@ -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 );
diff --git a/roms/ipxe/src/tests/tcpip_test.c b/roms/ipxe/src/tests/tcpip_test.c
index fac0ec26d..759f886bc 100644
--- a/roms/ipxe/src/tests/tcpip_test.c
+++ b/roms/ipxe/src/tests/tcpip_test.c
@@ -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 );
diff --git a/roms/ipxe/src/tests/tests.c b/roms/ipxe/src/tests/tests.c
index 0ec885f4f..54ce86677 100644
--- a/roms/ipxe/src/tests/tests.c
+++ b/roms/ipxe/src/tests/tests.c
@@ -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 );
diff --git a/roms/ipxe/src/tests/uri_test.c b/roms/ipxe/src/tests/uri_test.c
index 92c2f9037..da7fb8abe 100644
--- a/roms/ipxe/src/tests/uri_test.c
+++ b/roms/ipxe/src/tests/uri_test.c
@@ -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 );
diff --git a/roms/ipxe/src/tests/vsprintf_test.c b/roms/ipxe/src/tests/vsprintf_test.c
index f388b3ded..0ad4f1c56 100644
--- a/roms/ipxe/src/tests/vsprintf_test.c
+++ b/roms/ipxe/src/tests/vsprintf_test.c
@@ -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 */
diff --git a/roms/ipxe/src/usr/autoboot.c b/roms/ipxe/src/usr/autoboot.c
index 57bf96ef2..912543828 100644
--- a/roms/ipxe/src/usr/autoboot.c
+++ b/roms/ipxe/src/usr/autoboot.c
@@ -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
index 7857664d6..000000000
--- a/roms/ipxe/src/usr/ibmgmt.c
+++ /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 );
- }
-}
diff --git a/roms/ipxe/src/usr/ifmgmt.c b/roms/ipxe/src/usr/ifmgmt.c
index f367149f7..aefdaa45d 100644
--- a/roms/ipxe/src/usr/ifmgmt.c
+++ b/roms/ipxe/src/usr/ifmgmt.c
@@ -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
*
diff --git a/roms/ipxe/src/usr/lotest.c b/roms/ipxe/src/usr/lotest.c
index 6b75b5048..6b328713c 100644
--- a/roms/ipxe/src/usr/lotest.c
+++ b/roms/ipxe/src/usr/lotest.c
@@ -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
index 765c6dc9e..000000000
--- a/roms/ipxe/src/usr/ntpmgmt.c
+++ /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;
-}
diff --git a/roms/ipxe/src/util/efifatbin.c b/roms/ipxe/src/util/efifatbin.c
index 918e7a3c4..c02f750b6 100644
--- a/roms/ipxe/src/util/efifatbin.c
+++ b/roms/ipxe/src/util/efifatbin.c
@@ -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__ )
diff --git a/roms/ipxe/src/util/efirom.c b/roms/ipxe/src/util/efirom.c
index 943a66910..abee496dd 100644
--- a/roms/ipxe/src/util/efirom.c
+++ b/roms/ipxe/src/util/efirom.c
@@ -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:
diff --git a/roms/ipxe/src/util/elf2efi.c b/roms/ipxe/src/util/elf2efi.c
index 152bf5333..e68fa5d14 100644
--- a/roms/ipxe/src/util/elf2efi.c
+++ b/roms/ipxe/src/util/elf2efi.c
@@ -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>
@@ -27,90 +29,18 @@
#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
index 7064f99b6..000000000
--- a/roms/ipxe/src/util/genefidsk
+++ /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}
diff --git a/roms/ipxe/src/util/geniso b/roms/ipxe/src/util/geniso
index ff090d4a0..521c929e1 100755
--- a/roms/ipxe/src/util/geniso
+++ b/roms/ipxe/src/util/geniso
@@ -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
diff --git a/roms/ipxe/src/util/parserom.pl b/roms/ipxe/src/util/parserom.pl
index 5a849a540..28df60652 100755
--- a/roms/ipxe/src/util/parserom.pl
+++ b/roms/ipxe/src/util/parserom.pl
@@ -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";
diff --git a/roms/ipxe/src/util/zbin.c b/roms/ipxe/src/util/zbin.c
index 75fba583f..1862a3827 100644
--- a/roms/ipxe/src/util/zbin.c
+++ b/roms/ipxe/src/util/zbin.c
@@ -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;
}
diff --git a/roms/openbios/arch/amd64/context.c b/roms/openbios/arch/amd64/context.c
index 33ab51e62..2e4df6a3d 100644
--- a/roms/openbios/arch/amd64/context.c
+++ b/roms/openbios/arch/amd64/context.c
@@ -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;
}
diff --git a/roms/openbios/arch/ppc/build.xml b/roms/openbios/arch/ppc/build.xml
index e6063136f..29f6601f9 100644
--- a/roms/openbios/arch/ppc/build.xml
+++ b/roms/openbios/arch/ppc/build.xml
@@ -182,8 +182,6 @@
$(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
index 78205a27c..000000000
--- a/roms/openbios/arch/ppc/qemu/context.c
+++ /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
index 8135bb4c1..000000000
--- a/roms/openbios/arch/ppc/qemu/context.h
+++ /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 */
diff --git a/roms/openbios/arch/ppc/qemu/init.c b/roms/openbios/arch/ppc/qemu/init.c
index 8f264f41d..b76c5706f 100644
--- a/roms/openbios/arch/ppc/qemu/init.c
+++ b/roms/openbios/arch/ppc/qemu/init.c
@@ -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)
diff --git a/roms/openbios/arch/ppc/qemu/ldscript b/roms/openbios/arch/ppc/qemu/ldscript
index 11ebf4b39..8027b39db 100644
--- a/roms/openbios/arch/ppc/qemu/ldscript
+++ b/roms/openbios/arch/ppc/qemu/ldscript
@@ -51,11 +51,7 @@ SECTIONS
*(.bss)
*(.bss.*)
*(COMMON)
-
- _stack = .;
- . += CSTACK_SIZE;
- . = ALIGN(16);
- _estack = .;
+ _ebss = .;
}
. = HRESET_ADDR;
diff --git a/roms/openbios/arch/ppc/qemu/ofmem.c b/roms/openbios/arch/ppc/qemu/ofmem.c
index 7b8ced0e0..6f346a3d4 100644
--- a/roms/openbios/arch/ppc/qemu/ofmem.c
+++ b/roms/openbios/arch/ppc/qemu/ofmem.c
@@ -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);
diff --git a/roms/openbios/arch/ppc/qemu/start.S b/roms/openbios/arch/ppc/qemu/start.S
index 33ca1e03e..ae2fd53dc 100644
--- a/roms/openbios/arch/ppc/qemu/start.S
+++ b/roms/openbios/arch/ppc/qemu/start.S
@@ -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
index c3d9d7078..000000000
--- a/roms/openbios/arch/ppc/qemu/switch.S
+++ /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
diff --git a/roms/openbios/arch/sparc32/openbios.c b/roms/openbios/arch/sparc32/openbios.c
index 10ac9b9f3..6f4ee454e 100644
--- a/roms/openbios/arch/sparc32/openbios.c
+++ b/roms/openbios/arch/sparc32/openbios.c
@@ -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':
diff --git a/roms/openbios/arch/sparc64/context.c b/roms/openbios/arch/sparc64/context.c
index 823116f11..98932ee9c 100644
--- a/roms/openbios/arch/sparc64/context.c
+++ b/roms/openbios/arch/sparc64/context.c
@@ -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;
}
diff --git a/roms/openbios/forth/bootstrap/interpreter.fs b/roms/openbios/forth/bootstrap/interpreter.fs
index f02000f8e..51870581f 100644
--- a/roms/openbios/forth/bootstrap/interpreter.fs
+++ b/roms/openbios/forth/bootstrap/interpreter.fs
@@ -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
diff --git a/roms/openbios/forth/lib/build.xml b/roms/openbios/forth/lib/build.xml
index f1c9a45f2..34eee4072 100644
--- a/roms/openbios/forth/lib/build.xml
+++ b/roms/openbios/forth/lib/build.xml
@@ -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
index c095a9efd..000000000
--- a/roms/openbios/forth/lib/rstack.fs
+++ /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
diff --git a/roms/openbios/include/arch/ppc/io.h b/roms/openbios/include/arch/ppc/io.h
index 39c60d7e6..3449c5bf0 100644
--- a/roms/openbios/include/arch/ppc/io.h
+++ b/roms/openbios/include/arch/ppc/io.h
@@ -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))
diff --git a/roms/seabios/.version b/roms/seabios/.version
index 904325020..89c0c6acb 100644
--- a/roms/seabios/.version
+++ b/roms/seabios/.version
@@ -1 +1 @@
-rel-1.9.3-0-ge2fc41e
+rel-1.9.1-0-gb3ef39f
diff --git a/roms/seabios/scripts/layoutrom.py b/roms/seabios/scripts/layoutrom.py
index 6616721d1..b976fb056 100755
--- a/roms/seabios/scripts/layoutrom.py
+++ b/roms/seabios/scripts/layoutrom.py
@@ -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 ;
diff --git a/roms/seabios/src/fw/paravirt.c b/roms/seabios/src/fw/paravirt.c
index e8e419ea8..3fae13a83 100644
--- a/roms/seabios/src/fw/paravirt.c
+++ b/roms/seabios/src/fw/paravirt.c
@@ -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
diff --git a/roms/seabios/src/fw/pciinit.c b/roms/seabios/src/fw/pciinit.c
index 66e9f5a5f..c31c2fa0c 100644
--- a/roms/seabios/src/fw/pciinit.c
+++ b/roms/seabios/src/fw/pciinit.c
@@ -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) */
diff --git a/roms/seabios/src/fw/smp.c b/roms/seabios/src/fw/smp.c
index 6e706e42a..579acdbd0 100644
--- a/roms/seabios/src/fw/smp.c
+++ b/roms/seabios/src/fw/smp.c
@@ -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)
@@ -20,20 +20,20 @@
#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));
diff --git a/rules.mak b/rules.mak
index 99cd0b337..d1ff31125 100644
--- 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
index a8108d9b8..000000000
--- a/scripts/analyze-inclusions
+++ /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
diff --git a/scripts/checkpatch.pl b/scripts/checkpatch.pl
index b0096a446..c939a325b 100755
--- a/scripts/checkpatch.pl
+++ b/scripts/checkpatch.pl
@@ -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
index 54ab99ae2..000000000
--- a/scripts/clean-header-guards.pl
+++ /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";
-}
diff --git a/scripts/clean-includes b/scripts/clean-includes
index 4412a5590..72b47f17f 100755
--- a/scripts/clean-includes
+++ b/scripts/clean-includes
@@ -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"
diff --git a/scripts/cocci-macro-file.h b/scripts/cocci-macro-file.h
index 9f2e72e7e..eceb4be73 100644
--- a/scripts/cocci-macro-file.h
+++ b/scripts/cocci-macro-file.h
@@ -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
index 1316cc86a..000000000
--- a/scripts/coccinelle/err-bad-newline.cocci
+++ /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
index c23638007..000000000
--- a/scripts/coccinelle/error_propagate_null.cocci
+++ /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
index 08ec4a8de..000000000
--- a/scripts/coccinelle/overflow_muldiv64.cocci
+++ /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
index 9261c9968..000000000
--- a/scripts/coccinelle/remove_local_err.cocci
+++ /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
index 4c10bd57d..000000000
--- a/scripts/coccinelle/remove_muldiv64.cocci
+++ /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
index 48680f2c2..000000000
--- a/scripts/coccinelle/return_directly.cocci
+++ /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
index ed0677328..000000000
--- a/scripts/coccinelle/round.cocci
+++ /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
index 3d7c9744a..000000000
--- a/scripts/coccinelle/simplify_muldiv64.cocci
+++ /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
index b48b0d084..000000000
--- a/scripts/coccinelle/swap_muldiv64.cocci
+++ /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)
diff --git a/scripts/create_config b/scripts/create_config
index 1dd6a354f..9cb176f1b 100755
--- a/scripts/create_config
+++ b/scripts/create_config
@@ -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=*)
diff --git a/scripts/dump-guest-memory.py b/scripts/dump-guest-memory.py
index 9956fc036..c0a2e99f4 100644
--- a/scripts/dump-guest-memory.py
+++ b/scripts/dump-guest-memory.py
@@ -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():
diff --git a/scripts/feature_to_c.sh b/scripts/feature_to_c.sh
index c8ce9b88f..fb1f3363f 100644
--- a/scripts/feature_to_c.sh
+++ b/scripts/feature_to_c.sh
@@ -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
index 000000000..27d217a4c
--- /dev/null
+++ b/scripts/kvm/kvm_stat
@@ -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
index 000000000..6ce00d80e
--- /dev/null
+++ b/scripts/kvm/kvm_stat.texi
@@ -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
diff --git a/scripts/make_device_config.sh b/scripts/make_device_config.sh
index 354af317b..c1afb3ffa 100644
--- a/scripts/make_device_config.sh
+++ b/scripts/make_device_config.sh
@@ -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
diff --git a/scripts/qapi-commands.py b/scripts/qapi-commands.py
index a06a2c4f9..b570069fa 100644
--- a/scripts/qapi-commands.py
+++ b/scripts/qapi-commands.py
@@ -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)
diff --git a/scripts/qapi-event.py b/scripts/qapi-event.py
index 38d82111a..9b5c5b535 100644
--- a/scripts/qapi-event.py
+++ b/scripts/qapi-event.py
@@ -14,18 +14,18 @@
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)
diff --git a/scripts/qapi-introspect.py b/scripts/qapi-introspect.py
index 541644e35..e0f926be0 100644
--- a/scripts/qapi-introspect.py
+++ b/scripts/qapi-introspect.py
@@ -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)})
diff --git a/scripts/qapi-types.py b/scripts/qapi-types.py
index dabc42e04..437cf6c8e 100644
--- a/scripts/qapi-types.py
+++ b/scripts/qapi-types.py
@@ -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))
diff --git a/scripts/qapi-visit.py b/scripts/qapi-visit.py
index 96f2491c1..6c1c1fb3f 100644
--- a/scripts/qapi-visit.py
+++ b/scripts/qapi-visit.py
@@ -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);
}
diff --git a/scripts/qapi.py b/scripts/qapi.py
index 21bc32fda..b13ae4789 100644
--- a/scripts/qapi.py
+++ b/scripts/qapi.py
@@ -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
#
diff --git a/scripts/qemu-binfmt-conf.sh b/scripts/qemu-binfmt-conf.sh
index de4d1c13d..289b1a396 100755..100644
--- a/scripts/qemu-binfmt-conf.sh
+++ b/scripts/qemu-binfmt-conf.sh
@@ -1,323 +1,72 @@
#!/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
index 6d1b6230b..000000000
--- a/scripts/qemu.py
+++ /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
index e69de29bb..000000000
--- a/scripts/qmp/__init__.py
+++ /dev/null
diff --git a/scripts/qmp/qmp.py b/scripts/qmp/qmp.py
index 62d365196..779332f32 100644
--- a/scripts/qmp/qmp.py
+++ b/scripts/qmp/qmp.py
@@ -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):
"""
diff --git a/scripts/qtest.py b/scripts/qtest.py
index d5aecb5f4..a9714453a 100644
--- a/scripts/qtest.py
+++ b/scripts/qtest.py
@@ -13,11 +13,6 @@
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)
diff --git a/scripts/signrom.py b/scripts/signrom.py
index d1dabe024..f9c35ccfc 100644
--- a/scripts/signrom.py
+++ b/scripts/signrom.py
@@ -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
diff --git a/scripts/tracetool/backend/dtrace.py b/scripts/tracetool/backend/dtrace.py
index ab9ecfab3..fabfe9988 100644
--- a/scripts/tracetool/backend/dtrace.py
+++ b/scripts/tracetool/backend/dtrace.py
@@ -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()))
diff --git a/scripts/tracetool/backend/ftrace.py b/scripts/tracetool/backend/ftrace.py
index 80dcf3047..d798c7134 100644
--- a/scripts/tracetool/backend/ftrace.py
+++ b/scripts/tracetool/backend/ftrace.py
@@ -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(),
diff --git a/scripts/tracetool/backend/log.py b/scripts/tracetool/backend/log.py
index b3ff06401..e409b7326 100644
--- a/scripts/tracetool/backend/log.py
+++ b/scripts/tracetool/backend/log.py
@@ -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)
diff --git a/scripts/tracetool/backend/simple.py b/scripts/tracetool/backend/simple.py
index 1bccada63..3246c2001 100644
--- a/scripts/tracetool/backend/simple.py
+++ b/scripts/tracetool/backend/simple.py
@@ -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:
diff --git a/scripts/tracetool/backend/ust.py b/scripts/tracetool/backend/ust.py
index ed4c227f6..2f8f44abd 100644
--- a/scripts/tracetool/backend/ust.py
+++ b/scripts/tracetool/backend/ust.py
@@ -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)
diff --git a/scripts/tracetool/format/events_c.py b/scripts/tracetool/format/events_c.py
index 401206328..1cc6a49a7 100644
--- a/scripts/tracetool/format/events_c.py
+++ b/scripts/tracetool/format/events_c.py
@@ -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())
diff --git a/scripts/tracetool/format/events_h.py b/scripts/tracetool/format/events_h.py
index a9da60b7f..4529263e0 100644
--- a/scripts/tracetool/format/events_h.py
+++ b/scripts/tracetool/format/events_h.py
@@ -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(),
diff --git a/scripts/tracetool/format/h.py b/scripts/tracetool/format/h.py
index 3763e9aec..083540621 100644
--- a/scripts/tracetool/format/h.py
+++ b/scripts/tracetool/format/h.py
@@ -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)
diff --git a/scripts/tracetool/format/tcg_helper_c.py b/scripts/tracetool/format/tcg_helper_c.py
index e3485b7f9..a089b0bf0 100644
--- a/scripts/tracetool/format/tcg_helper_c.py
+++ b/scripts/tracetool/format/tcg_helper_c.py
@@ -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"',
'',
diff --git a/scripts/update-linux-headers.sh b/scripts/update-linux-headers.sh
index 08c4c4ae5..f7d62d974 100755
--- a/scripts/update-linux-headers.sh
+++ b/scripts/update-linux-headers.sh
@@ -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"
diff --git a/scripts/vmstate-static-checker.py b/scripts/vmstate-static-checker.py
index 14a27e7f6..b5ecaf644 100755
--- a/scripts/vmstate-static-checker.py
+++ b/scripts/vmstate-static-checker.py
@@ -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:
diff --git a/slirp/Makefile.objs b/slirp/Makefile.objs
index 1baa1f1c7..6748e4f60 100644
--- a/slirp/Makefile.objs
+++ b/slirp/Makefile.objs
@@ -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
diff --git a/slirp/bootp.c b/slirp/bootp.c
index 5a4646c18..7b3232bdc 100644
--- a/slirp/bootp.c
+++ b/slirp/bootp.c
@@ -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.
diff --git a/slirp/bootp.h b/slirp/bootp.h
index 394525733..ec3b68704 100644
--- a/slirp/bootp.h
+++ b/slirp/bootp.h
@@ -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
diff --git a/slirp/cksum.c b/slirp/cksum.c
index 6d73abf4a..2ad0e6540 100644
--- a/slirp/cksum.c
+++ b/slirp/cksum.c
@@ -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
index 02c51c775..000000000
--- a/slirp/dhcpv6.c
+++ /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
index 9189cd3f2..000000000
--- a/slirp/dhcpv6.h
+++ /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
diff --git a/slirp/dnssearch.c b/slirp/dnssearch.c
index 8fb563321..aed2f13af 100644
--- a/slirp/dnssearch.c
+++ b/slirp/dnssearch.c
@@ -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;
diff --git a/slirp/if.c b/slirp/if.c
index 51ae0d0e9..9b02180db 100644
--- a/slirp/if.c
+++ b/slirp/if.c
@@ -6,7 +6,7 @@
*/
#include "qemu/osdep.h"
-#include "slirp.h"
+#include <slirp.h>
#include "qemu/timer.h"
static void
diff --git a/slirp/if.h b/slirp/if.h
index 69569c10d..c7a5c5724 100644
--- a/slirp/if.h
+++ b/slirp/if.h
@@ -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 */
diff --git a/slirp/ip.h b/slirp/ip.h
index 1df672335..e2ee5e304 100644
--- a/slirp/ip.h
+++ b/slirp/ip.h
@@ -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
diff --git a/slirp/ip6.h b/slirp/ip6.h
index 0908855f0..8ddfa242c 100644
--- a/slirp/ip6.h
+++ b/slirp/ip6.h
@@ -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"
@@ -26,12 +26,6 @@
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])
diff --git a/slirp/ip6_icmp.c b/slirp/ip6_icmp.c
index 6d18e2898..09571bcd6 100644
--- a/slirp/ip6_icmp.c
+++ b/slirp/ip6_icmp.c
@@ -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);
diff --git a/slirp/ip6_icmp.h b/slirp/ip6_icmp.h
index b3378b17b..9460bf837 100644
--- a/slirp/ip6_icmp.h
+++ b/slirp/ip6_icmp.h
@@ -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.
diff --git a/slirp/ip_icmp.h b/slirp/ip_icmp.h
index d88ab34c1..846761d08 100644
--- a/slirp/ip_icmp.h
+++ b/slirp/ip_icmp.h
@@ -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.
diff --git a/slirp/ip_input.c b/slirp/ip_input.c
index 348e1dca5..cdd54833a 100644
--- a/slirp/ip_input.c
+++ b/slirp/ip_input.c
@@ -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);
diff --git a/slirp/ip_output.c b/slirp/ip_output.c
index db403f04c..0d6b3b831 100644
--- a/slirp/ip_output.c
+++ b/slirp/ip_output.c
@@ -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) */
diff --git a/slirp/libslirp.h b/slirp/libslirp.h
index f90f0f524..127aa41d4 100644
--- a/slirp/libslirp.h
+++ b/slirp/libslirp.h
@@ -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,
diff --git a/slirp/main.h b/slirp/main.h
index 90053ce5e..f2e58cfe2 100644
--- a/slirp/main.h
+++ b/slirp/main.h
@@ -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>
diff --git a/slirp/mbuf.c b/slirp/mbuf.c
index 7eddc217e..d13698839 100644
--- a/slirp/mbuf.c
+++ b/slirp/mbuf.c
@@ -16,7 +16,7 @@
*/
#include "qemu/osdep.h"
-#include "slirp.h"
+#include <slirp.h>
#define MBUF_THRESH 30
diff --git a/slirp/mbuf.h b/slirp/mbuf.h
index 893601ff9..36fb81409 100644
--- a/slirp/mbuf.h
+++ b/slirp/mbuf.h
@@ -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 */
diff --git a/slirp/misc.c b/slirp/misc.c
index 88e9d9419..2fbd04856 100644
--- a/slirp/misc.c
+++ b/slirp/misc.c
@@ -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
diff --git a/slirp/misc.h b/slirp/misc.h
index 5211bbd30..0d0c059e6 100644
--- a/slirp/misc.h
+++ b/slirp/misc.h
@@ -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? */
diff --git a/slirp/sbuf.c b/slirp/sbuf.c
index 10119d3ad..dd4cb8c13 100644
--- a/slirp/sbuf.c
+++ b/slirp/sbuf.c
@@ -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);
diff --git a/slirp/sbuf.h b/slirp/sbuf.h
index efcec39a6..4f22e7c38 100644
--- a/slirp/sbuf.h
+++ b/slirp/sbuf.h
@@ -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)
diff --git a/slirp/slirp.c b/slirp/slirp.c
index d67eda12f..9f4bea3d3 100644
--- a/slirp/slirp.c
+++ b/slirp/slirp.c
@@ -30,10 +30,6 @@
#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);
diff --git a/slirp/slirp.h b/slirp/slirp.h
index a1f313913..203deec48 100644
--- a/slirp/slirp.h
+++ b/slirp/slirp.h
@@ -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))
diff --git a/slirp/slirp_config.h b/slirp/slirp_config.h
index c59f65520..896d8022e 100644
--- a/slirp/slirp_config.h
+++ b/slirp/slirp_config.h
@@ -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 */
@@ -16,12 +29,34 @@
/* 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
@@ -34,6 +69,13 @@
#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
@@ -58,6 +100,9 @@
#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
@@ -70,17 +115,71 @@
/* 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
diff --git a/slirp/socket.c b/slirp/socket.c
index 280050a21..b336586c7 100644
--- a/slirp/socket.c
+++ b/slirp/socket.c
@@ -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;
}
diff --git a/slirp/socket.h b/slirp/socket.h
index 8feed2aea..b602e69b9 100644
--- a/slirp/socket.h
+++ b/slirp/socket.h
@@ -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_ */
diff --git a/slirp/tcp.h b/slirp/tcp.h
index 174d3d960..61befcde5 100644
--- a/slirp/tcp.h
+++ b/slirp/tcp.h
@@ -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;
diff --git a/slirp/tcp_input.c b/slirp/tcp_input.c
index c5063a918..e2b5d4ebb 100644
--- a/slirp/tcp_input.c
+++ b/slirp/tcp_input.c
@@ -39,7 +39,7 @@
*/
#include "qemu/osdep.h"
-#include "slirp.h"
+#include <slirp.h>
#include "ip_icmp.h"
#define TCPREXMTTHRESH 3
diff --git a/slirp/tcp_output.c b/slirp/tcp_output.c
index 819db2734..99b0a9b1c 100644
--- a/slirp/tcp_output.c
+++ b/slirp/tcp_output.c
@@ -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,
diff --git a/slirp/tcp_subr.c b/slirp/tcp_subr.c
index ed16e1807..6b9fef200 100644
--- a/slirp/tcp_subr.c
+++ b/slirp/tcp_subr.c
@@ -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 */
diff --git a/slirp/tcp_timer.c b/slirp/tcp_timer.c
index f9060c7bf..8f5dd772a 100644
--- a/slirp/tcp_timer.c
+++ b/slirp/tcp_timer.c
@@ -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);
diff --git a/slirp/tcp_timer.h b/slirp/tcp_timer.h
index b25b3911d..ff17914f4 100644
--- a/slirp/tcp_timer.h
+++ b/slirp/tcp_timer.h
@@ -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
diff --git a/slirp/tcp_var.h b/slirp/tcp_var.h
index 0f8f187c5..004193fb6 100644
--- a/slirp/tcp_var.h
+++ b/slirp/tcp_var.h
@@ -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"
diff --git a/slirp/tcpip.h b/slirp/tcpip.h
index 7bdb971c5..124b4a9f6 100644
--- a/slirp/tcpip.h
+++ b/slirp/tcpip.h
@@ -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.
diff --git a/slirp/tftp.c b/slirp/tftp.c
index c1859066c..12b5ff6e2 100644
--- a/slirp/tftp.c
+++ b/slirp/tftp.c
@@ -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);
diff --git a/slirp/tftp.h b/slirp/tftp.h
index 2cd276dec..1cb1adf59 100644
--- a/slirp/tftp.h
+++ b/slirp/tftp.h
@@ -1,7 +1,6 @@
/* tftp defines */
-
#ifndef SLIRP_TFTP_H
-#define SLIRP_TFTP_H
+#define SLIRP_TFTP_H 1
#define TFTP_SESSIONS_MAX 20
diff --git a/slirp/udp.c b/slirp/udp.c
index 93d722479..247024fd8 100644
--- a/slirp/udp.c
+++ b/slirp/udp.c
@@ -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);
diff --git a/slirp/udp.h b/slirp/udp.h
index be657cf92..10cc7809b 100644
--- a/slirp/udp.h
+++ b/slirp/udp.h
@@ -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
diff --git a/slirp/udp6.c b/slirp/udp6.c
index 9fa314bc2..a23026f2e 100644
--- a/slirp/udp6.c
+++ b/slirp/udp6.c
@@ -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 &&
diff --git a/softmmu_template.h b/softmmu_template.h
index 284ab2c7b..208f808f3 100644
--- a/softmmu_template.h
+++ b/softmmu_template.h
@@ -116,6 +116,31 @@
# 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);
}
}
diff --git a/stubs/Makefile.objs b/stubs/Makefile.objs
index 55edd15d7..4b258a673 100644
--- a/stubs/Makefile.objs
+++ b/stubs/Makefile.objs
@@ -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
diff --git a/stubs/cpu-get-icount.c b/stubs/cpu-get-icount.c
index 2e8b63b22..3a6f2ab00 100644
--- a/stubs/cpu-get-icount.c
+++ b/stubs/cpu-get-icount.c
@@ -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
index 98b6dcee0..000000000
--- a/stubs/ipmi.c
+++ /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
index 427e77286..000000000
--- a/stubs/pc_madt_cpu_entry.c
+++ /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)
-{
-}
diff --git a/stubs/slirp.c b/stubs/slirp.c
index 42f7e1afd..dcae51f0e 100644
--- a/stubs/slirp.c
+++ b/stubs/slirp.c
@@ -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
index 9528c2c28..000000000
--- a/stubs/smbios_type_38.c
+++ /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
index fe59836fc..000000000
--- a/stubs/trace-control.c
+++ /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();
-}
diff --git a/target-alpha/cpu-qom.h b/target-alpha/cpu-qom.h
index bae494534..b01c6c82e 100644
--- a/target-alpha/cpu-qom.h
+++ b/target-alpha/cpu-qom.h
@@ -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
diff --git a/target-alpha/cpu.c b/target-alpha/cpu.c
index 6d01d7f75..8a155cae9 100644
--- a/target-alpha/cpu.c
+++ b/target-alpha/cpu.c
@@ -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)
diff --git a/target-alpha/cpu.h b/target-alpha/cpu.h
index ac5e801fb..420f2a53f 100644
--- a/target-alpha/cpu.h
+++ b/target-alpha/cpu.h
@@ -17,11 +17,10 @@
* 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__) */
diff --git a/target-alpha/fpu_helper.c b/target-alpha/fpu_helper.c
index 9645978aa..5ab7d5e64 100644
--- a/target-alpha/fpu_helper.c
+++ b/target-alpha/fpu_helper.c
@@ -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"
diff --git a/target-alpha/gdbstub.c b/target-alpha/gdbstub.c
index d64bcccfa..199f02842 100644
--- a/target-alpha/gdbstub.c
+++ b/target-alpha/gdbstub.c
@@ -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)
diff --git a/target-alpha/helper.c b/target-alpha/helper.c
index 85168b7ed..6dec2639b 100644
--- a/target-alpha/helper.c
+++ b/target-alpha/helper.c
@@ -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"
diff --git a/target-alpha/int_helper.c b/target-alpha/int_helper.c
index 19bebfe74..777e48d08 100644
--- a/target-alpha/int_helper.c
+++ b/target-alpha/int_helper.c
@@ -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"
diff --git a/target-alpha/machine.c b/target-alpha/machine.c
index 710b7835b..9ab092852 100644
--- a/target-alpha/machine.c
+++ b/target-alpha/machine.c
@@ -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)
{
diff --git a/target-alpha/mem_helper.c b/target-alpha/mem_helper.c
index 1b2be50be..7fee9a6e2 100644
--- a/target-alpha/mem_helper.c
+++ b/target-alpha/mem_helper.c
@@ -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);
diff --git a/target-alpha/sys_helper.c b/target-alpha/sys_helper.c
index bec1e178b..e2dec15b6 100644
--- a/target-alpha/sys_helper.c
+++ b/target-alpha/sys_helper.c
@@ -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"
diff --git a/target-alpha/translate.c b/target-alpha/translate.c
index 0ea0e6e14..5b86992dd 100644
--- a/target-alpha/translate.c
+++ b/target-alpha/translate.c
@@ -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");
diff --git a/target-alpha/vax_helper.c b/target-alpha/vax_helper.c
index 2b0c17827..e74ac3e04 100644
--- a/target-alpha/vax_helper.c
+++ b/target-alpha/vax_helper.c
@@ -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"
diff --git a/target-arm/Makefile.objs b/target-arm/Makefile.objs
index f20641163..82cbe6bba 100644
--- a/target-arm/Makefile.objs
+++ b/target-arm/Makefile.objs
@@ -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
index 6519d52ca..000000000
--- a/target-arm/arm-powerctl.c
+++ /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
index 98ee04989..000000000
--- a/target-arm/arm-powerctl.h
+++ /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
diff --git a/target-arm/arm-semi.c b/target-arm/arm-semi.c
index 7cac8734c..8be0645eb 100644
--- a/target-arm/arm-semi.c
+++ b/target-arm/arm-semi.c
@@ -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:
diff --git a/target-arm/arm_ldst.h b/target-arm/arm_ldst.h
index a76d89f62..35c2c4391 100644
--- a/target-arm/arm_ldst.h
+++ b/target-arm/arm_ldst.h
@@ -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"
diff --git a/target-arm/cpu-qom.h b/target-arm/cpu-qom.h
index 3991173d4..1061c08a1 100644
--- a/target-arm/cpu-qom.h
+++ b/target-arm/cpu-qom.h
@@ -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
diff --git a/target-arm/cpu.c b/target-arm/cpu.c
index ce8b8f4a5..e48e83acb 100644
--- a/target-arm/cpu.c
+++ b/target-arm/cpu.c
@@ -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()
};
diff --git a/target-arm/cpu.h b/target-arm/cpu.h
index 76d824d31..066ff678d 100644
--- a/target-arm/cpu.h
+++ b/target-arm/cpu.h
@@ -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"
@@ -29,10 +29,11 @@
# 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"
@@ -90,20 +91,10 @@
#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
diff --git a/target-arm/gdbstub.c b/target-arm/gdbstub.c
index 04c1208d0..3ba9aadd4 100644
--- a/target-arm/gdbstub.c
+++ b/target-arm/gdbstub.c
@@ -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
diff --git a/target-arm/gdbstub64.c b/target-arm/gdbstub64.c
index 49bc3fc52..634c6bc6f 100644
--- a/target-arm/gdbstub64.c
+++ b/target-arm/gdbstub64.c
@@ -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)
diff --git a/target-arm/helper-a64.c b/target-arm/helper-a64.c
index 41e48a41b..c7bfb4d8f 100644
--- a/target-arm/helper-a64.c
+++ b/target-arm/helper-a64.c
@@ -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);
diff --git a/target-arm/helper.c b/target-arm/helper.c
index bdb842cc4..09638b2e7 100644
--- a/target-arm/helper.c
+++ b/target-arm/helper.c
@@ -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;
}
diff --git a/target-arm/internals.h b/target-arm/internals.h
index cd574017c..2e70272be 100644
--- a/target-arm/internals.h
+++ b/target-arm/internals.h
@@ -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
diff --git a/target-arm/kvm-stub.c b/target-arm/kvm-stub.c
index b2c66df53..38bf43387 100644
--- a/target-arm/kvm-stub.c
+++ b/target-arm/kvm-stub.c
@@ -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)
diff --git a/target-arm/kvm.c b/target-arm/kvm.c
index dbe393c10..36710320f 100644
--- a/target-arm/kvm.c
+++ b/target-arm/kvm.c
@@ -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;
diff --git a/target-arm/kvm32.c b/target-arm/kvm32.c
index 069da0c5f..d44a7f92b 100644
--- a/target-arm/kvm32.c
+++ b/target-arm/kvm32.c
@@ -10,18 +10,18 @@
#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;
-}
diff --git a/target-arm/kvm64.c b/target-arm/kvm64.c
index 5faa76c57..e8527bf0c 100644
--- a/target-arm/kvm64.c
+++ b/target-arm/kvm64.c
@@ -11,13 +11,13 @@
#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);
diff --git a/target-arm/kvm_arm.h b/target-arm/kvm_arm.h
index a4193684a..345233c18 100644
--- a/target-arm/kvm_arm.h
+++ b/target-arm/kvm_arm.h
@@ -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)
diff --git a/target-arm/machine.c b/target-arm/machine.c
index 7a6ca31a8..03a73d950 100644
--- a/target-arm/machine.c
+++ b/target-arm/machine.c
@@ -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);
}
diff --git a/target-arm/monitor.c b/target-arm/monitor.c
index 299cb80ae..1ee59a2e4 100644
--- a/target-arm/monitor.c
+++ b/target-arm/monitor.c
@@ -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);
diff --git a/target-arm/neon_helper.c b/target-arm/neon_helper.c
index ebdf7c9b1..1f1844f5b 100644
--- a/target-arm/neon_helper.c
+++ b/target-arm/neon_helper.c
@@ -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--; \
} \
diff --git a/target-arm/op_helper.c b/target-arm/op_helper.c
index 3e8588ee6..d626ff1a2 100644
--- a/target-arm/op_helper.c
+++ b/target-arm/op_helper.c
@@ -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:
diff --git a/target-arm/psci.c b/target-arm/psci.c
index 14316eb0a..c55487f87 100644
--- a/target-arm/psci.c
+++ b/target-arm/psci.c
@@ -16,13 +16,12 @@
* 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);
}
diff --git a/target-arm/translate-a64.c b/target-arm/translate-a64.c
index f5e29d20a..b13cff756 100644
--- a/target-arm/translate-a64.c
+++ b/target-arm/translate-a64.c
@@ -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))) {
diff --git a/target-arm/translate.c b/target-arm/translate.c
index bd5d5cb57..940ec8d98 100644
--- a/target-arm/translate.c
+++ b/target-arm/translate.c
@@ -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;
}
}
diff --git a/target-arm/translate.h b/target-arm/translate.h
index dbd7ac83d..6a18d7bad 100644
--- a/target-arm/translate.h
+++ b/target-arm/translate.h
@@ -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];
diff --git a/target-cris/cpu-qom.h b/target-cris/cpu-qom.h
index 7556e9f97..df4c0b50a 100644
--- a/target-cris/cpu-qom.h
+++ b/target-cris/cpu-qom.h
@@ -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
diff --git a/target-cris/cpu.c b/target-cris/cpu.c
index c5a656bb6..1cb79dd97 100644
--- a/target-cris/cpu.c
+++ b/target-cris/cpu.c
@@ -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)
diff --git a/target-cris/cpu.h b/target-cris/cpu.h
index 7d7fe6eb1..415cf9143 100644
--- a/target-cris/cpu.h
+++ b/target-cris/cpu.h
@@ -17,12 +17,10 @@
* 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
diff --git a/target-cris/crisv32-decode.h b/target-cris/crisv32-decode.h
index cdc2f8cbe..cdba37781 100644
--- a/target-cris/crisv32-decode.h
+++ b/target-cris/crisv32-decode.h
@@ -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
diff --git a/target-cris/gdbstub.c b/target-cris/gdbstub.c
index 3a72ee2a9..1bbf17b04 100644
--- a/target-cris/gdbstub.c
+++ b/target-cris/gdbstub.c
@@ -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)
diff --git a/target-cris/helper.c b/target-cris/helper.c
index af78cca8b..1eb9fd918 100644
--- a/target-cris/helper.c
+++ b/target-cris/helper.c
@@ -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"
diff --git a/target-cris/machine.c b/target-cris/machine.c
index 6b797e8c1..9cc2820e8 100644
--- a/target-cris/machine.c
+++ b/target-cris/machine.c
@@ -19,10 +19,7 @@
*/
#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",
diff --git a/target-cris/mmu.c b/target-cris/mmu.c
index b8db90882..4278d2dce 100644
--- a/target-cris/mmu.c
+++ b/target-cris/mmu.c
@@ -20,7 +20,6 @@
#include "qemu/osdep.h"
#include "cpu.h"
-#include "exec/exec-all.h"
#include "mmu.h"
#ifdef DEBUG
diff --git a/target-cris/op_helper.c b/target-cris/op_helper.c
index 504303913..320f2b80d 100644
--- a/target-cris/op_helper.c
+++ b/target-cris/op_helper.c
@@ -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 */
diff --git a/target-cris/translate.c b/target-cris/translate.c
index f4a8d7d00..5227f6576 100644
--- a/target-cris/translate.c
+++ b/target-cris/translate.c
@@ -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,
diff --git a/target-cris/translate_v10.c b/target-cris/translate_v10.c
index 4707a18e7..06ba1ef86 100644
--- a/target-cris/translate_v10.c
+++ b/target-cris/translate_v10.c
@@ -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,
diff --git a/target-i386/bpt_helper.c b/target-i386/bpt_helper.c
index 6fd7fe04a..f47df1998 100644
--- a/target-i386/bpt_helper.c
+++ b/target-i386/bpt_helper.c
@@ -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 {
diff --git a/target-i386/cpu-qom.h b/target-i386/cpu-qom.h
index 5dde658ac..cb750176c 100644
--- a/target-i386/cpu-qom.h
+++ b/target-i386/cpu-qom.h
@@ -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
diff --git a/target-i386/cpu.c b/target-i386/cpu.c
index 6a1afab59..da5d081c0 100644
--- a/target-i386/cpu.c
+++ b/target-i386/cpu.c
@@ -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"
@@ -35,16 +34,15 @@
#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().
diff --git a/target-i386/cpu.h b/target-i386/cpu.h
index 65615c0f3..ea8675878 100644
--- a/target-i386/cpu.h
+++ b/target-i386/cpu.h
@@ -16,12 +16,10 @@
* 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
@@ -130,6 +128,8 @@
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 */
@@ -159,6 +159,7 @@
#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)
@@ -290,7 +291,6 @@
#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
@@ -300,9 +300,6 @@
#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 */
@@ -330,10 +327,6 @@
#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
@@ -349,7 +342,6 @@
#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 */
diff --git a/target-i386/excp_helper.c b/target-i386/excp_helper.c
index f0dc4996c..ef37f4240 100644
--- a/target-i386/excp_helper.c
+++ b/target-i386/excp_helper.c
@@ -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"
diff --git a/target-i386/fpu_helper.c b/target-i386/fpu_helper.c
index 929489bfc..fee5573a1 100644
--- a/target-i386/fpu_helper.c
+++ b/target-i386/fpu_helper.c
@@ -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)
diff --git a/target-i386/gdbstub.c b/target-i386/gdbstub.c
index c494535df..4b5071398 100644
--- a/target-i386/gdbstub.c
+++ b/target-i386/gdbstub.c
@@ -19,7 +19,6 @@
*/
#include "qemu/osdep.h"
#include "qemu-common.h"
-#include "cpu.h"
#include "exec/gdbstub.h"
#ifdef TARGET_X86_64
diff --git a/target-i386/helper.c b/target-i386/helper.c
index 1c250b824..bf3e76207 100644
--- a/target-i386/helper.c
+++ b/target-i386/helper.c
@@ -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;
}
diff --git a/target-i386/hyperv.h b/target-i386/hyperv.h
index 0c3b56201..b26201f8b 100644
--- a/target-i386/hyperv.h
+++ b/target-i386/hyperv.h
@@ -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"
diff --git a/target-i386/int_helper.c b/target-i386/int_helper.c
index 9e873ac15..cf5bbb048 100644
--- a/target-i386/int_helper.c
+++ b/target-i386/int_helper.c
@@ -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"
diff --git a/target-i386/kvm-stub.c b/target-i386/kvm-stub.c
index cdf150610..8df9c5953 100644
--- a/target-i386/kvm-stub.c
+++ b/target-i386/kvm-stub.c
@@ -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)
diff --git a/target-i386/kvm.c b/target-i386/kvm.c
index d1a25c546..799fdfa68 100644
--- a/target-i386/kvm.c
+++ b/target-i386/kvm.c
@@ -15,16 +15,17 @@
#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
@@ -59,10 +57,6 @@
#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;
}
diff --git a/target-i386/machine.c b/target-i386/machine.c
index 71c0e4dc4..ee5b94922 100644
--- a/target-i386/machine.c
+++ b/target-i386/machine.c
@@ -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
}
};
diff --git a/target-i386/mem_helper.c b/target-i386/mem_helper.c
index 5bc0594df..85e75161b 100644
--- a/target-i386/mem_helper.c
+++ b/target-i386/mem_helper.c
@@ -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;
diff --git a/target-i386/misc_helper.c b/target-i386/misc_helper.c
index 3f666b4b8..e31ec976a 100644
--- a/target-i386/misc_helper.c
+++ b/target-i386/misc_helper.c
@@ -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"
diff --git a/target-i386/mpx_helper.c b/target-i386/mpx_helper.c
index 7e4482065..4d1785ece 100644
--- a/target-i386/mpx_helper.c
+++ b/target-i386/mpx_helper.c
@@ -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)
diff --git a/target-i386/seg_helper.c b/target-i386/seg_helper.c
index 6cbdf1742..b5f3d72fe 100644
--- a/target-i386/seg_helper.c
+++ b/target-i386/seg_helper.c
@@ -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)
{
diff --git a/target-i386/svm.h b/target-i386/svm.h
index 922c8fd39..04193ed60 100644
--- a/target-i386/svm.h
+++ b/target-i386/svm.h
@@ -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
diff --git a/target-i386/svm_helper.c b/target-i386/svm_helper.c
index 782b3f12f..ab472f6ee 100644
--- a/target-i386/svm_helper.c
+++ b/target-i386/svm_helper.c
@@ -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
index 05c5453d3..000000000
--- a/target-i386/trace-events
+++ /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"
diff --git a/target-i386/translate.c b/target-i386/translate.c
index fa2ac4817..922347caf 100644
--- a/target-i386/translate.c
+++ b/target-i386/translate.c
@@ -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));
diff --git a/target-lm32/cpu-qom.h b/target-lm32/cpu-qom.h
index b423d2564..77bc7b268 100644
--- a/target-lm32/cpu-qom.h
+++ b/target-lm32/cpu-qom.h
@@ -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
diff --git a/target-lm32/cpu.c b/target-lm32/cpu.c
index a783d461d..6e7e1b8e6 100644
--- a/target-lm32/cpu.c
+++ b/target-lm32/cpu.c
@@ -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)
diff --git a/target-lm32/cpu.h b/target-lm32/cpu.h
index d8a351524..f220fc0bb 100644
--- a/target-lm32/cpu.h
+++ b/target-lm32/cpu.h
@@ -17,15 +17,14 @@
* 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
diff --git a/target-lm32/gdbstub.c b/target-lm32/gdbstub.c
index cf929dd39..8ac1288bb 100644
--- a/target-lm32/gdbstub.c
+++ b/target-lm32/gdbstub.c
@@ -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"
diff --git a/target-lm32/helper.c b/target-lm32/helper.c
index 891da18c3..655248f81 100644
--- a/target-lm32/helper.c
+++ b/target-lm32/helper.c
@@ -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 {
diff --git a/target-lm32/machine.c b/target-lm32/machine.c
index 3c258a4bc..91c943d19 100644
--- a/target-lm32/machine.c
+++ b/target-lm32/machine.c
@@ -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",
diff --git a/target-lm32/op_helper.c b/target-lm32/op_helper.c
index 2177c8ad1..b6759e022 100644
--- a/target-lm32/op_helper.c
+++ b/target-lm32/op_helper.c
@@ -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 */
diff --git a/target-lm32/translate.c b/target-lm32/translate.c
index 2d8caebbf..256a51f84 100644
--- a/target-lm32/translate.c
+++ b/target-lm32/translate.c
@@ -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,
diff --git a/target-m68k/cpu-qom.h b/target-m68k/cpu-qom.h
index 9885bba31..c28e55d6b 100644
--- a/target-m68k/cpu-qom.h
+++ b/target-m68k/cpu-qom.h
@@ -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
diff --git a/target-m68k/cpu.c b/target-m68k/cpu.c
index 116b784e6..0b5f9a581 100644
--- a/target-m68k/cpu.c
+++ b/target-m68k/cpu.c
@@ -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)
diff --git a/target-m68k/cpu.h b/target-m68k/cpu.h
index b2faa6b60..48b4c872f 100644
--- a/target-m68k/cpu.h
+++ b/target-m68k/cpu.h
@@ -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
diff --git a/target-m68k/gdbstub.c b/target-m68k/gdbstub.c
index c7f44c9bb..f02bb5caf 100644
--- a/target-m68k/gdbstub.c
+++ b/target-m68k/gdbstub.c
@@ -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)
diff --git a/target-m68k/helper.c b/target-m68k/helper.c
index f52d0e303..a8f6d9d6a 100644
--- a/target-m68k/helper.c
+++ b/target-m68k/helper.c
@@ -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);
diff --git a/target-m68k/m68k-semi.c b/target-m68k/m68k-semi.c
index 1402145c8..f360ef3e1 100644
--- a/target-m68k/m68k-semi.c
+++ b/target-m68k/m68k-semi.c
@@ -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
diff --git a/target-m68k/op_helper.c b/target-m68k/op_helper.c
index e41ae4649..17d0a1191 100644
--- a/target-m68k/op_helper.c
+++ b/target-m68k/op_helper.c
@@ -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 */
diff --git a/target-m68k/translate.c b/target-m68k/translate.c
index ecd5e5c8f..7560c3a80 100644
--- a/target-m68k/translate.c
+++ b/target-m68k/translate.c
@@ -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);
diff --git a/target-microblaze/cpu-qom.h b/target-microblaze/cpu-qom.h
index 1a61db77d..34f6273ad 100644
--- a/target-microblaze/cpu-qom.h
+++ b/target-microblaze/cpu-qom.h
@@ -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
diff --git a/target-microblaze/cpu.c b/target-microblaze/cpu.c
index 8edc00a79..fdfb01917 100644
--- a/target-microblaze/cpu.c
+++ b/target-microblaze/cpu.c
@@ -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;
diff --git a/target-microblaze/cpu.h b/target-microblaze/cpu.h
index beb75ffd2..2f7335eaa 100644
--- a/target-microblaze/cpu.h
+++ b/target-microblaze/cpu.h
@@ -16,12 +16,10 @@
* 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
diff --git a/target-microblaze/gdbstub.c b/target-microblaze/gdbstub.c
index 7fb076c2e..89d38980b 100644
--- a/target-microblaze/gdbstub.c
+++ b/target-microblaze/gdbstub.c
@@ -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)
diff --git a/target-microblaze/helper.c b/target-microblaze/helper.c
index da394d1df..4de6bdbf8 100644
--- a/target-microblaze/helper.c
+++ b/target-microblaze/helper.c
@@ -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"
diff --git a/target-microblaze/mmu.c b/target-microblaze/mmu.c
index a22a496eb..4ac304035 100644
--- a/target-microblaze/mmu.c
+++ b/target-microblaze/mmu.c
@@ -20,7 +20,6 @@
#include "qemu/osdep.h"
#include "cpu.h"
-#include "exec/exec-all.h"
#define D(x)
diff --git a/target-microblaze/op_helper.c b/target-microblaze/op_helper.c
index 4a856e620..97333881f 100644
--- a/target-microblaze/op_helper.c
+++ b/target-microblaze/op_helper.c
@@ -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)
@@ -33,12 +32,12 @@
* 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;
}
diff --git a/target-microblaze/translate.c b/target-microblaze/translate.c
index 80098ece1..f944965a1 100644
--- a/target-microblaze/translate.c
+++ b/target-microblaze/translate.c
@@ -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),
diff --git a/target-mips/cpu-qom.h b/target-mips/cpu-qom.h
index 3f5bf2382..4d6f9de2e 100644
--- a/target-mips/cpu-qom.h
+++ b/target-mips/cpu-qom.h
@@ -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
diff --git a/target-mips/cpu.c b/target-mips/cpu.c
index 64ad112f4..0e2ecbebe 100644
--- a/target-mips/cpu.c
+++ b/target-mips/cpu.c
@@ -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)
diff --git a/target-mips/cpu.h b/target-mips/cpu.h
index 5182dc74f..866924d18 100644
--- a/target-mips/cpu.h
+++ b/target-mips/cpu.h
@@ -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__) */
diff --git a/target-mips/gdbstub.c b/target-mips/gdbstub.c
index 7c682289c..b0b4a32ec 100644
--- a/target-mips/gdbstub.c
+++ b/target-mips/gdbstub.c
@@ -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. */
diff --git a/target-mips/helper.c b/target-mips/helper.c
index c864b15b9..cfea177ee 100644
--- a/target-mips/helper.c
+++ b/target-mips/helper.c
@@ -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);
-}
diff --git a/target-mips/helper.h b/target-mips/helper.h
index 666936c81..594341d25 100644
--- a/target-mips/helper.h
+++ b/target-mips/helper.h
@@ -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) \
diff --git a/target-mips/kvm.c b/target-mips/kvm.c
index dcf5fbba0..950bc05b7 100644
--- a/target-mips/kvm.c
+++ b/target-mips/kvm.c
@@ -11,15 +11,16 @@
#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();
diff --git a/target-mips/kvm_mips.h b/target-mips/kvm_mips.h
index ae957f37f..54f59656e 100644
--- a/target-mips/kvm_mips.h
+++ b/target-mips/kvm_mips.h
@@ -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__ */
diff --git a/target-mips/machine.c b/target-mips/machine.c
index a27f2f156..22bca1814 100644
--- a/target-mips/machine.c
+++ b/target-mips/machine.c
@@ -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),
diff --git a/target-mips/mips-defs.h b/target-mips/mips-defs.h
index 047554ee4..53b185ebd 100644
--- a/target-mips/mips-defs.h
+++ b/target-mips/mips-defs.h
@@ -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__) */
diff --git a/target-mips/mips-semi.c b/target-mips/mips-semi.c
index a7aefbaef..ed235de99 100644
--- a/target-mips/mips-semi.c
+++ b/target-mips/mips-semi.c
@@ -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"
diff --git a/target-mips/msa_helper.c b/target-mips/msa_helper.c
index 1fdb0d979..654a0d272 100644
--- a/target-mips/msa_helper.c
+++ b/target-mips/msa_helper.c
@@ -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)
diff --git a/target-mips/op_helper.c b/target-mips/op_helper.c
index ea2f2abe1..ba847ab3a 100644
--- a/target-mips/op_helper.c
+++ b/target-mips/op_helper.c
@@ -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)
diff --git a/target-mips/translate.c b/target-mips/translate.c
index bab52cb25..a3a05ec66 100644
--- a/target-mips/translate.c
+++ b/target-mips/translate.c
@@ -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;
diff --git a/target-mips/translate_init.c b/target-mips/translate_init.c
index 39ed5c4c1..5af077d0d 100644
--- a/target-mips/translate_init.c
+++ b/target-mips/translate_init.c
@@ -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);
}
diff --git a/target-moxie/cpu.c b/target-moxie/cpu.c
index 50a089947..b4ee84e90 100644
--- a/target-moxie/cpu.c
+++ b/target-moxie/cpu.c
@@ -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)
{
diff --git a/target-moxie/cpu.h b/target-moxie/cpu.h
index 3e880facf..4ee207796 100644
--- a/target-moxie/cpu.h
+++ b/target-moxie/cpu.h
@@ -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 */
diff --git a/target-moxie/helper.c b/target-moxie/helper.c
index 330299f5a..d51e9b9cc 100644
--- a/target-moxie/helper.c
+++ b/target-moxie/helper.c
@@ -29,12 +29,12 @@
/* 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);
diff --git a/target-moxie/machine.c b/target-moxie/machine.c
index 282dcd869..912b79139 100644
--- a/target-moxie/machine.c
+++ b/target-moxie/machine.c
@@ -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",
diff --git a/target-moxie/mmu.h b/target-moxie/mmu.h
index 284a44d18..abc79297c 100644
--- a/target-moxie/mmu.h
+++ b/target-moxie/mmu.h
@@ -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;
diff --git a/target-moxie/translate.c b/target-moxie/translate.c
index 0660b44c0..a437e2ab6 100644
--- a/target-moxie/translate.c
+++ b/target-moxie/translate.c
@@ -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) {
diff --git a/target-openrisc/cpu.c b/target-openrisc/cpu.c
index 155913f10..ae6ed9e92 100644
--- a/target-openrisc/cpu.c
+++ b/target-openrisc/cpu.c
@@ -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)
{
diff --git a/target-openrisc/cpu.h b/target-openrisc/cpu.h
index aaf153579..4b63f2580 100644
--- a/target-openrisc/cpu.h
+++ b/target-openrisc/cpu.h
@@ -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 */
diff --git a/target-openrisc/exception.c b/target-openrisc/exception.c
index 49470be05..ace3184d5 100644
--- a/target-openrisc/exception.c
+++ b/target-openrisc/exception.c
@@ -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)
diff --git a/target-openrisc/exception.h b/target-openrisc/exception.h
index 4ec56b465..4b64430df 100644
--- a/target-openrisc/exception.h
+++ b/target-openrisc/exception.h
@@ -17,12 +17,12 @@
* 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 */
diff --git a/target-openrisc/gdbstub.c b/target-openrisc/gdbstub.c
index cb16e7635..edc301a7c 100644
--- a/target-openrisc/gdbstub.c
+++ b/target-openrisc/gdbstub.c
@@ -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)
diff --git a/target-openrisc/interrupt.c b/target-openrisc/interrupt.c
index 5fe3f11ff..963eb1478 100644
--- a/target-openrisc/interrupt.c
+++ b/target-openrisc/interrupt.c
@@ -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"
diff --git a/target-openrisc/interrupt_helper.c b/target-openrisc/interrupt_helper.c
index 116f9109a..11b4b2056 100644
--- a/target-openrisc/interrupt_helper.c
+++ b/target-openrisc/interrupt_helper.c
@@ -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)
diff --git a/target-openrisc/machine.c b/target-openrisc/machine.c
index 17b0c77d6..b4dc08dfe 100644
--- a/target-openrisc/machine.c
+++ b/target-openrisc/machine.c
@@ -18,11 +18,8 @@
*/
#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",
diff --git a/target-openrisc/mmu.c b/target-openrisc/mmu.c
index 505dcdcdc..4ab414a68 100644
--- a/target-openrisc/mmu.c
+++ b/target-openrisc/mmu.c
@@ -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"
diff --git a/target-openrisc/mmu_helper.c b/target-openrisc/mmu_helper.c
index a44d0aa51..d7952d449 100644
--- a/target-openrisc/mmu_helper.c
+++ b/target-openrisc/mmu_helper.c
@@ -20,17 +20,16 @@
#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) {
diff --git a/target-openrisc/sys_helper.c b/target-openrisc/sys_helper.c
index a719e452b..f917be6be 100644
--- a/target-openrisc/sys_helper.c
+++ b/target-openrisc/sys_helper.c
@@ -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))
diff --git a/target-openrisc/translate.c b/target-openrisc/translate.c
index 28c944657..5d0ab442a 100644
--- a/target-openrisc/translate.c
+++ b/target-openrisc/translate.c
@@ -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",
diff --git a/target-ppc/cpu-qom.h b/target-ppc/cpu-qom.h
index 286410502..7d5e2b36a 100644
--- a/target-ppc/cpu-qom.h
+++ b/target-ppc/cpu-qom.h
@@ -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"
@@ -38,127 +39,6 @@
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;
diff --git a/target-ppc/cpu.h b/target-ppc/cpu.h
index 786ab5cdf..5282533b3 100644
--- a/target-ppc/cpu.h
+++ b/target-ppc/cpu.h
@@ -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)
@@ -85,6 +86,93 @@
#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__) */
diff --git a/target-ppc/excp_helper.c b/target-ppc/excp_helper.c
index d6e1678a6..ca4ffe8ad 100644
--- a/target-ppc/excp_helper.c
+++ b/target-ppc/excp_helper.c
@@ -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 */
diff --git a/target-ppc/fpu_helper.c b/target-ppc/fpu_helper.c
index d9795d04d..b67ebca12 100644
--- a/target-ppc/fpu_helper.c
+++ b/target-ppc/fpu_helper.c
@@ -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)
diff --git a/target-ppc/gdbstub.c b/target-ppc/gdbstub.c
index 7a338136a..569c380cf 100644
--- a/target-ppc/gdbstub.c
+++ b/target-ppc/gdbstub.c
@@ -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)
diff --git a/target-ppc/helper.h b/target-ppc/helper.h
index 1f5cfd099..e5a8f7b9b 100644
--- a/target-ppc/helper.h
+++ b/target-ppc/helper.h
@@ -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)
diff --git a/target-ppc/helper_regs.h b/target-ppc/helper_regs.h
index 3d279f1d8..271fddf17 100644
--- a/target-ppc/helper_regs.h
+++ b/target-ppc/helper_regs.h
@@ -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__) */
diff --git a/target-ppc/int_helper.c b/target-ppc/int_helper.c
index 74453763d..27b0258d3 100644
--- a/target-ppc/int_helper.c
+++ b/target-ppc/int_helper.c
@@ -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"
diff --git a/target-ppc/kvm-stub.c b/target-ppc/kvm-stub.c
index efeafca1d..627bcb432 100644
--- a/target-ppc/kvm-stub.c
+++ b/target-ppc/kvm-stub.c
@@ -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)
diff --git a/target-ppc/kvm.c b/target-ppc/kvm.c
index dcb68b908..c4c81467e 100644
--- a/target-ppc/kvm.c
+++ b/target-ppc/kvm.c
@@ -17,18 +17,18 @@
#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;
diff --git a/target-ppc/kvm_ppc.h b/target-ppc/kvm_ppc.h
index 5461d1082..fc7931227 100644
--- a/target-ppc/kvm_ppc.h
+++ b/target-ppc/kvm_ppc.h
@@ -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__ */
diff --git a/target-ppc/machine.c b/target-ppc/machine.c
index 4820f2237..46684fb93 100644
--- a/target-ppc/machine.c
+++ b/target-ppc/machine.c
@@ -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;
}
diff --git a/target-ppc/mem_helper.c b/target-ppc/mem_helper.c
index e4ed3773e..6d584c912 100644
--- a/target-ppc/mem_helper.c
+++ b/target-ppc/mem_helper.c
@@ -18,12 +18,10 @@
*/
#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
diff --git a/target-ppc/misc_helper.c b/target-ppc/misc_helper.c
index cb5ebf56c..73e3b0583 100644
--- a/target-ppc/misc_helper.c
+++ b/target-ppc/misc_helper.c
@@ -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;
- }
-}
diff --git a/target-ppc/mmu-hash32.c b/target-ppc/mmu-hash32.c
index 29bace622..39abb2fd3 100644
--- a/target-ppc/mmu-hash32.c
+++ b/target-ppc/mmu-hash32.c
@@ -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);
diff --git a/target-ppc/mmu-hash32.h b/target-ppc/mmu-hash32.h
index 5b9fb08d1..afbb9dd3d 100644
--- a/target-ppc/mmu-hash32.h
+++ b/target-ppc/mmu-hash32.h
@@ -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__ */
diff --git a/target-ppc/mmu-hash64.c b/target-ppc/mmu-hash64.c
index 5de1358d1..72c4ab5d7 100644
--- a/target-ppc/mmu-hash64.c
+++ b/target-ppc/mmu-hash64.c
@@ -20,10 +20,10 @@
#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);
-}
diff --git a/target-ppc/mmu-hash64.h b/target-ppc/mmu-hash64.h
index db265e30b..9bf8b9b26 100644
--- a/target-ppc/mmu-hash64.h
+++ b/target-ppc/mmu-hash64.h
@@ -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__) */
diff --git a/target-ppc/mmu_helper.c b/target-ppc/mmu_helper.c
index 3eb3cd78e..ff217941b 100644
--- a/target-ppc/mmu_helper.c
+++ b/target-ppc/mmu_helper.c
@@ -24,10 +24,8 @@
#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)) {
diff --git a/target-ppc/timebase_helper.c b/target-ppc/timebase_helper.c
index a07faa42c..3b340d70d 100644
--- a/target-ppc/timebase_helper.c
+++ b/target-ppc/timebase_helper.c
@@ -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
index 8fcc3ce98..000000000
--- a/target-ppc/trace-events
+++ /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"
diff --git a/target-ppc/translate.c b/target-ppc/translate.c
index 92030b66a..b3860ecde 100644
--- a/target-ppc/translate.c
+++ b/target-ppc/translate.c
@@ -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;
diff --git a/target-ppc/translate_init.c b/target-ppc/translate_init.c
index 7a9b15e7e..f51572552 100644
--- a/target-ppc/translate_init.c
+++ b/target-ppc/translate_init.c
@@ -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"
@@ -31,13 +31,29 @@
#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) */
diff --git a/target-s390x/cc_helper.c b/target-s390x/cc_helper.c
index 1cf855133..0d9411bdf 100644
--- a/target-s390x/cc_helper.c
+++ b/target-s390x/cc_helper.c
@@ -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"
diff --git a/target-s390x/cpu-qom.h b/target-s390x/cpu-qom.h
index 66b5d1808..1c9093396 100644
--- a/target-s390x/cpu-qom.h
+++ b/target-s390x/cpu-qom.h
@@ -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
diff --git a/target-s390x/cpu.c b/target-s390x/cpu.c
index e43e2d615..4bfff341d 100644
--- a/target-s390x/cpu.c
+++ b/target-s390x/cpu.c
@@ -30,12 +30,10 @@
#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"
diff --git a/target-s390x/cpu.h b/target-s390x/cpu.h
index c216bdace..6d97c089a 100644
--- a/target-s390x/cpu.h
+++ b/target-s390x/cpu.h
@@ -19,12 +19,10 @@
* 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 */
diff --git a/target-s390x/fpu_helper.c b/target-s390x/fpu_helper.c
index e604e9f7b..1c7f67354 100644
--- a/target-s390x/fpu_helper.c
+++ b/target-s390x/fpu_helper.c
@@ -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 */
diff --git a/target-s390x/gdbstub.c b/target-s390x/gdbstub.c
index 3d223dec9..9fc36cb54 100644
--- a/target-s390x/gdbstub.c
+++ b/target-s390x/gdbstub.c
@@ -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"
diff --git a/target-s390x/helper.c b/target-s390x/helper.c
index 54a517734..92abe7e67 100644
--- a/target-s390x/helper.c
+++ b/target-s390x/helper.c
@@ -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 */
diff --git a/target-s390x/helper.h b/target-s390x/helper.h
index 207a6e7d1..7e06119e9 100644
--- a/target-s390x/helper.h
+++ b/target-s390x/helper.h
@@ -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)
diff --git a/target-s390x/int_helper.c b/target-s390x/int_helper.c
index 370c94da5..cc1071eea 100644
--- a/target-s390x/int_helper.c
+++ b/target-s390x/int_helper.c
@@ -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"
diff --git a/target-s390x/interrupt.c b/target-s390x/interrupt.c
index 9edef9679..bad60a7e1 100644
--- a/target-s390x/interrupt.c
+++ b/target-s390x/interrupt.c
@@ -10,77 +10,13 @@
#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()) {
diff --git a/target-s390x/ioinst.c b/target-s390x/ioinst.c
index a5a288bec..142ff9384 100644
--- a/target-s390x/ioinst.c
+++ b/target-s390x/ioinst.c
@@ -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);
diff --git a/include/hw/s390x/ioinst.h b/target-s390x/ioinst.h
index c559f5342..013cc9148 100644
--- a/include/hw/s390x/ioinst.h
+++ b/target-s390x/ioinst.h
@@ -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
diff --git a/target-s390x/kvm.c b/target-s390x/kvm.c
index 80ac6215f..e1859cae0 100644
--- a/target-s390x/kvm.c
+++ b/target-s390x/kvm.c
@@ -23,17 +23,18 @@
#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();
diff --git a/target-s390x/machine.c b/target-s390x/machine.c
index aa39e5daa..6b2609054 100644
--- a/target-s390x/machine.c
+++ b/target-s390x/machine.c
@@ -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
},
};
diff --git a/target-s390x/mem_helper.c b/target-s390x/mem_helper.c
index 99bc5e283..707862203 100644
--- a/target-s390x/mem_helper.c
+++ b/target-s390x/mem_helper.c
@@ -21,12 +21,8 @@
#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 */
@@ -36,12 +32,12 @@
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 */
diff --git a/target-s390x/misc_helper.c b/target-s390x/misc_helper.c
index 86da1947b..71cbe34e0 100644
--- a/target-s390x/misc_helper.c
+++ b/target-s390x/misc_helper.c
@@ -29,11 +29,10 @@
#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
index df59f5f19..000000000
--- a/target-s390x/trace-events
+++ /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"
diff --git a/target-s390x/translate.c b/target-s390x/translate.c
index 1a07d70b2..c871ef2bb 100644
--- a/target-s390x/translate.c
+++ b/target-s390x/translate.c
@@ -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");
diff --git a/target-sh4/cpu-qom.h b/target-sh4/cpu-qom.h
index 01abb206e..6341238aa 100644
--- a/target-sh4/cpu-qom.h
+++ b/target-sh4/cpu-qom.h
@@ -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
diff --git a/target-sh4/cpu.c b/target-sh4/cpu.c
index f589532e1..86ba38808 100644
--- a/target-sh4/cpu.c
+++ b/target-sh4/cpu.c
@@ -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)
diff --git a/target-sh4/cpu.h b/target-sh4/cpu.h
index 478ab5586..3b23e967b 100644
--- a/target-sh4/cpu.h
+++ b/target-sh4/cpu.h
@@ -16,12 +16,10 @@
* 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 */
diff --git a/target-sh4/gdbstub.c b/target-sh4/gdbstub.c
index 13bea00d7..1b59ea8c7 100644
--- a/target-sh4/gdbstub.c
+++ b/target-sh4/gdbstub.c
@@ -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 */
diff --git a/target-sh4/helper.c b/target-sh4/helper.c
index a33ac697c..6438338f2 100644
--- a/target-sh4/helper.c
+++ b/target-sh4/helper.c
@@ -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)
diff --git a/target-sh4/op_helper.c b/target-sh4/op_helper.c
index 684d3f375..368e687d6 100644
--- a/target-sh4/op_helper.c
+++ b/target-sh4/op_helper.c
@@ -19,17 +19,16 @@
#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;
}
diff --git a/target-sh4/translate.c b/target-sh4/translate.c
index ca80cf70c..7c189680a 100644
--- a/target-sh4/translate.c
+++ b/target-sh4/translate.c
@@ -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
index c9a184960..000000000
--- a/target-sparc/asi.h
+++ /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 */
diff --git a/target-sparc/cc_helper.c b/target-sparc/cc_helper.c
index a410a0b98..44c440934 100644
--- a/target-sparc/cc_helper.c
+++ b/target-sparc/cc_helper.c
@@ -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;
}
diff --git a/target-sparc/cpu-qom.h b/target-sparc/cpu-qom.h
index f63af728e..5096b1047 100644
--- a/target-sparc/cpu-qom.h
+++ b/target-sparc/cpu-qom.h
@@ -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
diff --git a/target-sparc/cpu.c b/target-sparc/cpu.c
index e4089f207..fe4119e2b 100644
--- a/target-sparc/cpu.c
+++ b/target-sparc/cpu.c
@@ -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;
diff --git a/target-sparc/cpu.h b/target-sparc/cpu.h
index a3d64a4e5..dc4612275 100644
--- a/target-sparc/cpu.h
+++ b/target-sparc/cpu.h
@@ -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
diff --git a/target-sparc/fop_helper.c b/target-sparc/fop_helper.c
index c7fb176e4..08306436a 100644
--- a/target-sparc/fop_helper.c
+++ b/target-sparc/fop_helper.c
@@ -19,60 +19,48 @@
#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
diff --git a/target-sparc/gdbstub.c b/target-sparc/gdbstub.c
index ffc2baa2e..e530dc52f 100644
--- a/target-sparc/gdbstub.c
+++ b/target-sparc/gdbstub.c
@@ -19,7 +19,6 @@
*/
#include "qemu/osdep.h"
#include "qemu-common.h"
-#include "cpu.h"
#include "exec/gdbstub.h"
#ifdef TARGET_ABI32
diff --git a/target-sparc/helper.c b/target-sparc/helper.c
index bedc6722a..8349cbe2c 100644
--- a/target-sparc/helper.c
+++ b/target-sparc/helper.c
@@ -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"
diff --git a/target-sparc/helper.h b/target-sparc/helper.h
index caa2a895d..4374f0dd2 100644
--- a/target-sparc/helper.h
+++ b/target-sparc/helper.h
@@ -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)
diff --git a/target-sparc/ldst_helper.c b/target-sparc/ldst_helper.c
index 6ce5ccc37..658e7d858 100644
--- a/target-sparc/ldst_helper.c
+++ b/target-sparc/ldst_helper.c
@@ -19,11 +19,8 @@
#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);
diff --git a/target-sparc/machine.c b/target-sparc/machine.c
index 59c92f758..1046016f3 100644
--- a/target-sparc/machine.c
+++ b/target-sparc/machine.c
@@ -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 = {
diff --git a/target-sparc/mmu_helper.c b/target-sparc/mmu_helper.c
index 32b629fb0..aa80c4829 100644
--- a/target-sparc/mmu_helper.c
+++ b/target-sparc/mmu_helper.c
@@ -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
index bf52d9769..000000000
--- a/target-sparc/trace-events
+++ /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"
diff --git a/target-sparc/translate.c b/target-sparc/translate.c
index e7691e445..502510c75 100644
--- a/target-sparc/translate.c
+++ b/target-sparc/translate.c
@@ -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),
diff --git a/target-tilegx/cpu.c b/target-tilegx/cpu.c
index 7017cb6e1..d2d091203 100644
--- a/target-tilegx/cpu.c
+++ b/target-tilegx/cpu.c
@@ -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)
diff --git a/target-tilegx/cpu.h b/target-tilegx/cpu.h
index 173542723..022cad186 100644
--- a/target-tilegx/cpu.h
+++ b/target-tilegx/cpu.h
@@ -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
diff --git a/target-tilegx/helper.c b/target-tilegx/helper.c
index b4fba9cc2..616c5c7cf 100644
--- a/target-tilegx/helper.c
+++ b/target-tilegx/helper.c
@@ -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 */
diff --git a/target-tilegx/opcode_tilegx.h b/target-tilegx/opcode_tilegx.h
index 55376be4c..989436d2f 100644
--- a/target-tilegx/opcode_tilegx.h
+++ b/target-tilegx/opcode_tilegx.h
@@ -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__ */
diff --git a/target-tilegx/translate.c b/target-tilegx/translate.c
index 11c973238..03918ebd5 100644
--- a/target-tilegx/translate.c
+++ b/target-tilegx/translate.c
@@ -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,
diff --git a/target-tricore/cpu-qom.h b/target-tricore/cpu-qom.h
index 6a6975612..66c966474 100644
--- a/target-tricore/cpu-qom.h
+++ b/target-tricore/cpu-qom.h
@@ -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 */
diff --git a/target-tricore/cpu.c b/target-tricore/cpu.c
index 35d4ee4de..69fca8c06 100644
--- a/target-tricore/cpu.c
+++ b/target-tricore/cpu.c
@@ -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)
{
diff --git a/target-tricore/cpu.h b/target-tricore/cpu.h
index a3493a123..90045a93d 100644
--- a/target-tricore/cpu.h
+++ b/target-tricore/cpu.h
@@ -16,13 +16,11 @@
* 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__ */
diff --git a/target-tricore/helper.c b/target-tricore/helper.c
index 3118905ec..71b31cdb9 100644
--- a/target-tricore/helper.c
+++ b/target-tricore/helper.c
@@ -18,7 +18,6 @@
#include "qemu/osdep.h"
#include "cpu.h"
-#include "exec/exec-all.h"
enum {
TLBRET_DIRTY = -4,
diff --git a/target-tricore/op_helper.c b/target-tricore/op_helper.c
index ac02e0a36..40656c357 100644
--- a/target-tricore/op_helper.c
+++ b/target-tricore/op_helper.c
@@ -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;
diff --git a/target-tricore/translate.c b/target-tricore/translate.c
index 9a50df9a8..26e86d6f6 100644
--- a/target-tricore/translate.c
+++ b/target-tricore/translate.c
@@ -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,
diff --git a/target-tricore/tricore-defs.h b/target-tricore/tricore-defs.h
index 40abfaac1..4350b0304 100644
--- a/target-tricore/tricore-defs.h
+++ b/target-tricore/tricore-defs.h
@@ -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__ */
diff --git a/target-unicore32/cpu-qom.h b/target-unicore32/cpu-qom.h
index bc68e7804..ea65b8331 100644
--- a/target-unicore32/cpu-qom.h
+++ b/target-unicore32/cpu-qom.h
@@ -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
diff --git a/target-unicore32/cpu.c b/target-unicore32/cpu.c
index e7a498426..66f43acff 100644
--- a/target-unicore32/cpu.c
+++ b/target-unicore32/cpu.c
@@ -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[] = {
diff --git a/target-unicore32/cpu.h b/target-unicore32/cpu.h
index 7b5b405e7..9c1fbf9b7 100644
--- a/target-unicore32/cpu.h
+++ b/target-unicore32/cpu.h
@@ -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 */
diff --git a/target-unicore32/helper.c b/target-unicore32/helper.c
index d603bde23..21f5f3574 100644
--- a/target-unicore32/helper.c
+++ b/target-unicore32/helper.c
@@ -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"
diff --git a/target-unicore32/op_helper.c b/target-unicore32/op_helper.c
index 0872c29fa..f5847307a 100644
--- a/target-unicore32/op_helper.c
+++ b/target-unicore32/op_helper.c
@@ -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 */
diff --git a/target-unicore32/softmmu.c b/target-unicore32/softmmu.c
index e7152e72e..d267fed87 100644
--- a/target-unicore32/softmmu.c
+++ b/target-unicore32/softmmu.c
@@ -13,8 +13,7 @@
#endif
#include "qemu/osdep.h"
-#include "cpu.h"
-#include "exec/exec-all.h"
+#include <cpu.h>
#undef DEBUG_UC32
diff --git a/target-unicore32/translate.c b/target-unicore32/translate.c
index 09354f92d..39af3af05 100644
--- a/target-unicore32/translate.c
+++ b/target-unicore32/translate.c
@@ -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);
diff --git a/target-xtensa/core-dc232b/core-isa.h b/target-xtensa/core-dc232b/core-isa.h
index a9935b87a..69f106557 100644
--- a/target-xtensa/core-dc232b/core-isa.h
+++ b/target-xtensa/core-dc232b/core-isa.h
@@ -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
@@ -419,4 +420,4 @@
#endif /* !XTENSA_HAL_NON_PRIVILEGED_ONLY */
-#endif /* XTENSA_DC232B_CORE_ISA_H */
+#endif /* _XTENSA_CORE_CONFIGURATION_H */
diff --git a/target-xtensa/core-dc233c/core-isa.h b/target-xtensa/core-dc233c/core-isa.h
index ff92b7f3e..e82c3cbe4 100644
--- a/target-xtensa/core-dc233c/core-isa.h
+++ b/target-xtensa/core-dc233c/core-isa.h
@@ -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 */
diff --git a/target-xtensa/core-fsf/core-isa.h b/target-xtensa/core-fsf/core-isa.h
index fb2bb8f2c..b519d6c74 100644
--- a/target-xtensa/core-fsf/core-isa.h
+++ b/target-xtensa/core-fsf/core-isa.h
@@ -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
@@ -357,4 +358,4 @@
#endif /* !XTENSA_HAL_NON_PRIVILEGED_ONLY */
-#endif /* XTENSA_FSF_CORE_ISA_H */
+#endif /* _XTENSA_CORE_CONFIGURATION_H */
diff --git a/target-xtensa/cpu-qom.h b/target-xtensa/cpu-qom.h
index 403bd9572..2258224d0 100644
--- a/target-xtensa/cpu-qom.h
+++ b/target-xtensa/cpu-qom.h
@@ -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
diff --git a/target-xtensa/cpu.c b/target-xtensa/cpu.c
index 5ad08a279..01b251fdc 100644
--- a/target-xtensa/cpu.c
+++ b/target-xtensa/cpu.c
@@ -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)
diff --git a/target-xtensa/cpu.h b/target-xtensa/cpu.h
index 7fe82a37a..d0bd9dada 100644
--- a/target-xtensa/cpu.h
+++ b/target-xtensa/cpu.h
@@ -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
diff --git a/target-xtensa/gdbstub.c b/target-xtensa/gdbstub.c
index fa5469a4e..51d4db083 100644
--- a/target-xtensa/gdbstub.c
+++ b/target-xtensa/gdbstub.c
@@ -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)
{
diff --git a/target-xtensa/helper.c b/target-xtensa/helper.c
index 768b32c41..839f4a74a 100644
--- a/target-xtensa/helper.c
+++ b/target-xtensa/helper.c
@@ -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);
}
}
}
diff --git a/target-xtensa/op_helper.c b/target-xtensa/op_helper.c
index 0a4b2147b..62fa33d8d 100644
--- a/target-xtensa/op_helper.c
+++ b/target-xtensa/op_helper.c
@@ -29,14 +29,12 @@
#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,
diff --git a/target-xtensa/translate.c b/target-xtensa/translate.c
index 4c1e48748..989448846 100644
--- a/target-xtensa/translate.c
+++ b/target-xtensa/translate.c
@@ -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);
diff --git a/tcg/aarch64/tcg-target.h b/tcg/aarch64/tcg-target.h
index a1d101f89..19a04a6e7 100644
--- a/tcg/aarch64/tcg-target.h
+++ b/tcg/aarch64/tcg-target.h
@@ -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 */
diff --git a/tcg/aarch64/tcg-target.inc.c b/tcg/aarch64/tcg-target.inc.c
index 08b2d031a..a8fb4420d 100644
--- a/tcg/aarch64/tcg-target.inc.c
+++ b/tcg/aarch64/tcg-target.inc.c
@@ -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:
diff --git a/tcg/arm/tcg-target.h b/tcg/arm/tcg-target.h
index a0e1acfa7..6559f80b7 100644
--- a/tcg/arm/tcg-target.h
+++ b/tcg/arm/tcg-target.h
@@ -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
diff --git a/tcg/arm/tcg-target.inc.c b/tcg/arm/tcg-target.inc.c
index 172febafd..2b7fbddbf 100644
--- a/tcg/arm/tcg-target.inc.c
+++ b/tcg/arm/tcg-target.inc.c
@@ -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)
{
diff --git a/tcg/i386/tcg-target.h b/tcg/i386/tcg-target.h
index 524cfc61f..92be34171 100644
--- a/tcg/i386/tcg-target.h
+++ b/tcg/i386/tcg-target.h
@@ -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
diff --git a/tcg/i386/tcg-target.inc.c b/tcg/i386/tcg-target.inc.c
index 6f8cdca75..007407c3f 100644
--- a/tcg/i386/tcg-target.inc.c
+++ b/tcg/i386/tcg-target.inc.c
@@ -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);
diff --git a/tcg/ia64/tcg-target.h b/tcg/ia64/tcg-target.h
index 6dddb7f77..ae9b79f02 100644
--- a/tcg/ia64/tcg-target.h
+++ b/tcg/ia64/tcg-target.h
@@ -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
diff --git a/tcg/ia64/tcg-target.inc.c b/tcg/ia64/tcg-target.inc.c
index c91f39281..7557e6a9d 100644
--- a/tcg/ia64/tcg-target.inc.c
+++ b/tcg/ia64/tcg-target.inc.c
@@ -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)
diff --git a/tcg/mips/tcg-target.h b/tcg/mips/tcg-target.h
index 3aeac8761..b1cda37b6 100644
--- a/tcg/mips/tcg-target.h
+++ b/tcg/mips/tcg-target.h
@@ -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
diff --git a/tcg/mips/tcg-target.inc.c b/tcg/mips/tcg-target.inc.c
index 2f9be4813..aaf881cfd 100644
--- a/tcg/mips/tcg-target.inc.c
+++ b/tcg/mips/tcg-target.inc.c
@@ -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);
}
diff --git a/tcg/optimize.c b/tcg/optimize.c
index cffe89b52..f01160815 100644
--- a/tcg/optimize.c
+++ b/tcg/optimize.c
@@ -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];
diff --git a/tcg/ppc/tcg-target.h b/tcg/ppc/tcg-target.h
index dd032f286..b4f081876 100644
--- a/tcg/ppc/tcg-target.h
+++ b/tcg/ppc/tcg-target.h
@@ -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
diff --git a/tcg/ppc/tcg-target.inc.c b/tcg/ppc/tcg-target.inc.c
index eaf1bd9bf..00bb90fc2 100644
--- a/tcg/ppc/tcg-target.inc.c
+++ b/tcg/ppc/tcg-target.inc.c
@@ -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:
{
diff --git a/tcg/s390/tcg-target.h b/tcg/s390/tcg-target.h
index 0c1af244f..d9dc03873 100644
--- a/tcg/s390/tcg-target.h
+++ b/tcg/s390/tcg-target.h
@@ -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
diff --git a/tcg/s390/tcg-target.inc.c b/tcg/s390/tcg-target.inc.c
index 5a7495b06..580553239 100644
--- a/tcg/s390/tcg-target.inc.c
+++ b/tcg/s390/tcg-target.inc.c
@@ -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):
diff --git a/tcg/sparc/tcg-target.h b/tcg/sparc/tcg-target.h
index 88f9c90f5..2cd72d2d4 100644
--- a/tcg/sparc/tcg-target.h
+++ b/tcg/sparc/tcg-target.h
@@ -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
diff --git a/tcg/sparc/tcg-target.inc.c b/tcg/sparc/tcg-target.inc.c
index 8e98172ca..d641cfd8c 100644
--- a/tcg/sparc/tcg-target.inc.c
+++ b/tcg/sparc/tcg-target.inc.c
@@ -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);
}
diff --git a/tcg/tcg-common.c b/tcg/tcg-common.c
index 2f139de80..97305a3ef 100644
--- a/tcg/tcg-common.c
+++ b/tcg/tcg-common.c
@@ -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)
diff --git a/tcg/tcg-op.c b/tcg/tcg-op.c
index 0243c9909..f554b86d4 100644
--- a/tcg/tcg-op.c
+++ b/tcg/tcg-op.c
@@ -23,13 +23,8 @@
*/
#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);
}
diff --git a/tcg/tcg-op.h b/tcg/tcg-op.h
index f217e8074..c446d3dc7 100644
--- a/tcg/tcg-op.h
+++ b/tcg/tcg-op.h
@@ -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
diff --git a/tcg/tcg.c b/tcg/tcg.c
index 42417bdc9..796addd1f 100644
--- 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"
@@ -40,11 +41,6 @@
#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
diff --git a/tcg/tcg.h b/tcg/tcg.h
index 1bcabcad9..40c8fbe2a 100644
--- a/tcg/tcg.h
+++ b/tcg/tcg.h
@@ -26,32 +26,9 @@
#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).
*
diff --git a/tcg/tci/tcg-target.h b/tcg/tci/tcg-target.h
index 868228b2e..3942f9ccc 100644
--- a/tcg/tci/tcg-target.h
+++ b/tcg/tci/tcg-target.h
@@ -37,9 +37,10 @@
* 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
diff --git a/tcg/tci/tcg-target.inc.c b/tcg/tci/tcg-target.inc.c
index 3c47ea7a9..e2fc52a16 100644
--- a/tcg/tci/tcg-target.inc.c
+++ b/tcg/tci/tcg-target.inc.c
@@ -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 b488c0d8e..82705fe77 100644
--- 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;
}
diff --git a/tests/.gitignore b/tests/.gitignore
index dbb52639f..9eed22988 100644
--- a/tests/.gitignore
+++ b/tests/.gitignore
@@ -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
diff --git a/tests/Makefile.include b/tests/Makefile
index 14be4915b..9194f1850 100644
--- a/tests/Makefile.include
+++ b/tests/Makefile
@@ -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
diff --git a/tests/ac97-test.c b/tests/ac97-test.c
index e0d177bd9..75cab8f98 100644
--- a/tests/ac97-test.c
+++ b/tests/ac97-test.c
@@ -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
index 1bf8a0a63..000000000
--- a/tests/acpi-test-data/pc/APIC.cphp
+++ /dev/null
Binary files differ
diff --git a/tests/acpi-test-data/pc/DSDT b/tests/acpi-test-data/pc/DSDT
index 8053d7110..9d1274d3c 100644
--- a/tests/acpi-test-data/pc/DSDT
+++ b/tests/acpi-test-data/pc/DSDT
Binary files differ
diff --git a/tests/acpi-test-data/pc/DSDT.bridge b/tests/acpi-test-data/pc/DSDT.bridge
index 850e71a97..cf48c62aa 100644
--- a/tests/acpi-test-data/pc/DSDT.bridge
+++ b/tests/acpi-test-data/pc/DSDT.bridge
Binary files differ
diff --git a/tests/acpi-test-data/pc/DSDT.cphp b/tests/acpi-test-data/pc/DSDT.cphp
deleted file mode 100644
index e8b146208..000000000
--- a/tests/acpi-test-data/pc/DSDT.cphp
+++ /dev/null
Binary files differ
diff --git a/tests/acpi-test-data/pc/DSDT.ipmikcs b/tests/acpi-test-data/pc/DSDT.ipmikcs
deleted file mode 100644
index 8ac48afb6..000000000
--- a/tests/acpi-test-data/pc/DSDT.ipmikcs
+++ /dev/null
Binary files differ
diff --git a/tests/acpi-test-data/q35/APIC.cphp b/tests/acpi-test-data/q35/APIC.cphp
deleted file mode 100644
index 1bf8a0a63..000000000
--- a/tests/acpi-test-data/q35/APIC.cphp
+++ /dev/null
Binary files differ
diff --git a/tests/acpi-test-data/q35/DSDT b/tests/acpi-test-data/q35/DSDT
index 58fbb3d2e..1c089c34b 100644
--- a/tests/acpi-test-data/q35/DSDT
+++ b/tests/acpi-test-data/q35/DSDT
Binary files differ
diff --git a/tests/acpi-test-data/q35/DSDT.bridge b/tests/acpi-test-data/q35/DSDT.bridge
index c392802a9..b29fcda0b 100644
--- a/tests/acpi-test-data/q35/DSDT.bridge
+++ b/tests/acpi-test-data/q35/DSDT.bridge
Binary files differ
diff --git a/tests/acpi-test-data/q35/DSDT.cphp b/tests/acpi-test-data/q35/DSDT.cphp
deleted file mode 100644
index 6cc28c6da..000000000
--- a/tests/acpi-test-data/q35/DSDT.cphp
+++ /dev/null
Binary files differ
diff --git a/tests/acpi-test-data/q35/DSDT.ipmibt b/tests/acpi-test-data/q35/DSDT.ipmibt
deleted file mode 100644
index 0ea38e1e7..000000000
--- a/tests/acpi-test-data/q35/DSDT.ipmibt
+++ /dev/null
Binary files differ
diff --git a/tests/ahci-test.c b/tests/ahci-test.c
index 9c0adce22..6869f7f46 100644
--- a/tests/ahci-test.c
+++ b/tests/ahci-test.c
@@ -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);
diff --git a/tests/bios-tables-test.c b/tests/bios-tables-test.c
index de4019e57..03528140c 100644
--- a/tests/bios-tables-test.c
+++ b/tests/bios-tables-test.c
@@ -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);
diff --git a/tests/boot-order-test.c b/tests/boot-order-test.c
index fc1e7941f..a6d8bd5cb 100644
--- a/tests/boot-order-test.c
+++ b/tests/boot-order-test.c
@@ -11,6 +11,7 @@
*/
#include "qemu/osdep.h"
+#include <glib.h>
#include "libqos/fw_cfg.h"
#include "libqtest.h"
diff --git a/tests/boot-sector.h b/tests/boot-sector.h
index f64b477aa..38be0290e 100644
--- a/tests/boot-sector.h
+++ b/tests/boot-sector.h
@@ -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 */
diff --git a/tests/check-qdict.c b/tests/check-qdict.c
index 42da1e65a..a43056c5d 100644
--- a/tests/check-qdict.c
+++ b/tests/check-qdict.c
@@ -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"
diff --git a/tests/check-qfloat.c b/tests/check-qfloat.c
index 1da2cdae0..3102608f5 100644
--- a/tests/check-qfloat.c
+++ b/tests/check-qfloat.c
@@ -11,6 +11,7 @@
*
*/
#include "qemu/osdep.h"
+#include <glib.h>
#include "qapi/qmp/qfloat.h"
#include "qemu-common.h"
diff --git a/tests/check-qint.c b/tests/check-qint.c
index b6e455511..c86f7dfa3 100644
--- a/tests/check-qint.c
+++ b/tests/check-qint.c
@@ -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"
diff --git a/tests/check-qjson.c b/tests/check-qjson.c
index 85955744e..99de6f525 100644
--- a/tests/check-qjson.c
+++ b/tests/check-qjson.c
@@ -11,9 +11,16 @@
*
*/
#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)
diff --git a/tests/check-qlist.c b/tests/check-qlist.c
index e16da5e5c..f231d5fa9 100644
--- a/tests/check-qlist.c
+++ b/tests/check-qlist.c
@@ -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
index dc906b116..000000000
--- a/tests/check-qnull.c
+++ /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();
-}
diff --git a/tests/check-qom-interface.c b/tests/check-qom-interface.c
index 719ddcf2e..09354deb7 100644
--- a/tests/check-qom-interface.c
+++ b/tests/check-qom-interface.c
@@ -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"
diff --git a/tests/check-qom-proplist.c b/tests/check-qom-proplist.c
index 42defe712..ffffd872f 100644
--- a/tests/check-qom-proplist.c
+++ b/tests/check-qom-proplist.c
@@ -19,6 +19,7 @@
*/
#include "qemu/osdep.h"
+#include <glib.h>
#include "qapi/error.h"
#include "qom/object.h"
diff --git a/tests/check-qstring.c b/tests/check-qstring.c
index 239e9d9da..9877b42c8 100644
--- a/tests/check-qstring.c
+++ b/tests/check-qstring.c
@@ -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
index 4bb721a4a..000000000
--- a/tests/data/test-qga-config
+++ /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
diff --git a/tests/device-introspect-test.c b/tests/device-introspect-test.c
index 37debc11f..447792601 100644
--- a/tests/device-introspect-test.c
+++ b/tests/device-introspect-test.c
@@ -18,6 +18,7 @@
*/
#include "qemu/osdep.h"
+#include <glib.h>
#include "qemu-common.h"
#include "qapi/qmp/qstring.h"
#include "libqtest.h"
diff --git a/tests/display-vga-test.c b/tests/display-vga-test.c
index 91460215c..5706d338a 100644
--- a/tests/display-vga-test.c
+++ b/tests/display-vga-test.c
@@ -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
index 4f4707dae..000000000
--- a/tests/docker/Makefile.include
+++ /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
index 0c6d8d5ec..000000000
--- a/tests/docker/common.rc
+++ /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
index 222a1053f..000000000
--- a/tests/docker/docker.py
+++ /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
index 8f4fe4637..000000000
--- a/tests/docker/dockerfiles/centos6.docker
+++ /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
index 3a9125e49..000000000
--- a/tests/docker/dockerfiles/debian-bootstrap.docker
+++ /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
index 5d9c8d5eb..000000000
--- a/tests/docker/dockerfiles/debian-bootstrap.pre
+++ /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
index 1d26a8e98..000000000
--- a/tests/docker/dockerfiles/fedora.docker
+++ /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
index a8b88c318..000000000
--- a/tests/docker/dockerfiles/ubuntu.docker
+++ /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
index d85d49afc..000000000
--- a/tests/docker/run
+++ /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
index 60e4e976b..000000000
--- a/tests/docker/test-clang
+++ /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
index fd9b79894..000000000
--- a/tests/docker/test-full
+++ /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
index c03757add..000000000
--- a/tests/docker/test-mingw
+++ /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
index 07cdc59a1..000000000
--- a/tests/docker/test-quick
+++ /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
index d345393ce..000000000
--- a/tests/docker/travis
+++ /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
index 8dcc964da..000000000
--- a/tests/docker/travis.py
+++ /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())
diff --git a/tests/drive_del-test.c b/tests/drive_del-test.c
index 121b9c917..fe03236f3 100644
--- a/tests/drive_del-test.c
+++ b/tests/drive_del-test.c
@@ -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",
diff --git a/tests/ds1338-test.c b/tests/ds1338-test.c
index 26968bc82..279241584 100644
--- a/tests/ds1338-test.c
+++ b/tests/ds1338-test.c
@@ -21,6 +21,8 @@
#include "libqtest.h"
#include "libqos/i2c.h"
+#include <glib.h>
+
#define IMX25_I2C_0_BASE 0x43F80000
#define DS1338_ADDR 0x68
diff --git a/tests/e1000-test.c b/tests/e1000-test.c
index 59cab68a6..a42b3810c 100644
--- a/tests/e1000-test.c
+++ b/tests/e1000-test.c
@@ -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
index d497b0857..000000000
--- a/tests/e1000e-test.c
+++ /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();
-}
diff --git a/tests/eepro100-test.c b/tests/eepro100-test.c
index ed23258b0..e17eed0b7 100644
--- a/tests/eepro100-test.c
+++ b/tests/eepro100-test.c
@@ -8,6 +8,7 @@
*/
#include "qemu/osdep.h"
+#include <glib.h>
#include "libqtest.h"
static void test_device(gconstpointer data)
diff --git a/tests/endianness-test.c b/tests/endianness-test.c
index b7a120e0a..cc5bccd88 100644
--- a/tests/endianness-test.c
+++ b/tests/endianness-test.c
@@ -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;
}
diff --git a/tests/es1370-test.c b/tests/es1370-test.c
index 199fe193c..824dc31c6 100644
--- a/tests/es1370-test.c
+++ b/tests/es1370-test.c
@@ -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/fdc-test.c b/tests/fdc-test.c
index 738c6b4a5..53df1d0d8 100644
--- a/tests/fdc-test.c
+++ b/tests/fdc-test.c
@@ -24,6 +24,7 @@
#include "qemu/osdep.h"
+#include <glib.h>
#include "libqtest.h"
#include "qemu-common.h"
diff --git a/tests/fw_cfg-test.c b/tests/fw_cfg-test.c
index 688342bed..b4392c2d3 100644
--- a/tests/fw_cfg-test.c
+++ b/tests/fw_cfg-test.c
@@ -11,6 +11,7 @@
*/
#include "qemu/osdep.h"
+#include <glib.h>
#include "libqtest.h"
#include "hw/nvram/fw_cfg_keys.h"
diff --git a/tests/hd-geo-test.c b/tests/hd-geo-test.c
index 12ee3929d..c8e669ac2 100644
--- a/tests/hd-geo-test.c
+++ b/tests/hd-geo-test.c
@@ -16,6 +16,7 @@
*/
#include "qemu/osdep.h"
+#include <glib.h>
#include "qemu-common.h"
#include "libqtest.h"
diff --git a/tests/i440fx-test.c b/tests/i440fx-test.c
index 3542ad114..05029e90b 100644
--- a/tests/i440fx-test.c
+++ b/tests/i440fx-test.c
@@ -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;
}
diff --git a/tests/i82801b11-test.c b/tests/i82801b11-test.c
index a6e31594c..c3b5ebbca 100644
--- a/tests/i82801b11-test.c
+++ b/tests/i82801b11-test.c
@@ -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/ide-test.c b/tests/ide-test.c
index 1e51af2a9..0d9ab4df9 100644
--- a/tests/ide-test.c
+++ b/tests/ide-test.c
@@ -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);
diff --git a/tests/intel-hda-test.c b/tests/intel-hda-test.c
index b782b2e94..1be6add9b 100644
--- a/tests/intel-hda-test.c
+++ b/tests/intel-hda-test.c
@@ -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;
}
diff --git a/tests/ioh3420-test.c b/tests/ioh3420-test.c
index b54c4b9f1..93eb2f750 100644
--- a/tests/ioh3420-test.c
+++ b/tests/ioh3420-test.c
@@ -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/ipmi-bt-test.c b/tests/ipmi-bt-test.c
index be9005eb8..812907fb7 100644
--- a/tests/ipmi-bt-test.c
+++ b/tests/ipmi-bt-test.c
@@ -29,6 +29,7 @@
#include <netinet/ip.h>
#include <netinet/tcp.h>
+#include <glib.h>
#include "libqtest.h"
#include "qemu-common.h"
diff --git a/tests/ipmi-kcs-test.c b/tests/ipmi-kcs-test.c
index 375038965..42c4b974c 100644
--- a/tests/ipmi-kcs-test.c
+++ b/tests/ipmi-kcs-test.c
@@ -24,6 +24,7 @@
#include "qemu/osdep.h"
+#include <glib.h>
#include "libqtest.h"
diff --git a/tests/ipoctal232-test.c b/tests/ipoctal232-test.c
index 684914164..846aaf571 100644
--- a/tests/ipoctal232-test.c
+++ b/tests/ipoctal232-test.c
@@ -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/ivshmem-test.c b/tests/ivshmem-test.c
index 0957ee755..c027ff1e0 100644
--- a/tests/ivshmem-test.c
+++ b/tests/ivshmem-test.c
@@ -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"
diff --git a/tests/libqos/ahci.c b/tests/libqos/ahci.c
index f3be5500e..ac6c155c8 100644
--- a/tests/libqos/ahci.c
+++ b/tests/libqos/ahci.c
@@ -23,6 +23,7 @@
*/
#include "qemu/osdep.h"
+#include <glib.h>
#include "libqtest.h"
#include "libqos/ahci.h"
diff --git a/tests/libqos/ahci.h b/tests/libqos/ahci.h
index c69fb5ae9..71dd7a6e5 100644
--- a/tests/libqos/ahci.h
+++ b/tests/libqos/ahci.h
@@ -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
diff --git a/tests/libqos/fw_cfg.c b/tests/libqos/fw_cfg.c
index 4d9dc3fd0..76894d575 100644
--- a/tests/libqos/fw_cfg.c
+++ b/tests/libqos/fw_cfg.c
@@ -13,6 +13,7 @@
*/
#include "qemu/osdep.h"
+#include <glib.h>
#include "libqos/fw_cfg.h"
#include "libqtest.h"
#include "qemu/bswap.h"
diff --git a/tests/libqos/i2c-imx.c b/tests/libqos/i2c-imx.c
index 1c4b4314b..51c3468f9 100644
--- a/tests/libqos/i2c-imx.c
+++ b/tests/libqos/i2c-imx.c
@@ -20,6 +20,7 @@
#include "qemu/osdep.h"
#include "libqos/i2c.h"
+#include <glib.h>
#include "libqtest.h"
diff --git a/tests/libqos/i2c-omap.c b/tests/libqos/i2c-omap.c
index f603fdf43..2028f2f14 100644
--- a/tests/libqos/i2c-omap.c
+++ b/tests/libqos/i2c-omap.c
@@ -9,6 +9,7 @@
#include "qemu/osdep.h"
#include "libqos/i2c.h"
+#include <glib.h>
#include "qemu/bswap.h"
#include "libqtest.h"
diff --git a/tests/libqos/libqos-pc.h b/tests/libqos/libqos-pc.h
index a0e4c4551..b1820c573 100644
--- a/tests/libqos/libqos-pc.h
+++ b/tests/libqos/libqos-pc.h
@@ -1,5 +1,5 @@
-#ifndef LIBQOS_PC_H
-#define LIBQOS_PC_H
+#ifndef __libqos_pc_h
+#define __libqos_pc_h
#include "libqos/libqos.h"
diff --git a/tests/libqos/libqos.c b/tests/libqos/libqos.c
index c7ba441d0..79b0b29b4 100644
--- a/tests/libqos/libqos.c
+++ b/tests/libqos/libqos.c
@@ -1,4 +1,5 @@
#include "qemu/osdep.h"
+#include <glib.h>
#include <sys/wait.h>
#include "libqtest.h"
diff --git a/tests/libqos/libqos.h b/tests/libqos/libqos.h
index 604980d12..ca14d2e9f 100644
--- a/tests/libqos/libqos.h
+++ b/tests/libqos/libqos.h
@@ -1,5 +1,5 @@
-#ifndef LIBQOS_H
-#define LIBQOS_H
+#ifndef __libqos_h
+#define __libqos_h
#include "libqtest.h"
#include "libqos/pci.h"
diff --git a/tests/libqos/malloc-generic.c b/tests/libqos/malloc-generic.c
index 33ce90b92..6000df2b8 100644
--- a/tests/libqos/malloc-generic.c
+++ b/tests/libqos/malloc-generic.c
@@ -8,6 +8,7 @@
*/
#include "qemu/osdep.h"
+#include <glib.h>
#include "libqos/malloc-generic.h"
#include "libqos/malloc.h"
diff --git a/tests/libqos/malloc-pc.c b/tests/libqos/malloc-pc.c
index dd2b900c5..eee706bd6 100644
--- a/tests/libqos/malloc-pc.c
+++ b/tests/libqos/malloc-pc.c
@@ -17,6 +17,7 @@
#include "hw/nvram/fw_cfg_keys.h"
#include "qemu-common.h"
+#include <glib.h>
#define PAGE_SIZE (4096)
diff --git a/tests/libqos/malloc.c b/tests/libqos/malloc.c
index b8eff5f49..c0df52f33 100644
--- a/tests/libqos/malloc.c
+++ b/tests/libqos/malloc.c
@@ -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;
diff --git a/tests/libqos/pci-pc.c b/tests/libqos/pci-pc.c
index 1ae2d3780..77f15e5a0 100644
--- a/tests/libqos/pci-pc.c
+++ b/tests/libqos/pci-pc.c
@@ -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
diff --git a/tests/libqos/pci.c b/tests/libqos/pci.c
index ed78d91ce..0e104e14e 100644
--- a/tests/libqos/pci.c
+++ b/tests/libqos/pci.c
@@ -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),
diff --git a/tests/libqos/usb.c b/tests/libqos/usb.c
index f794d92da..87efb9078 100644
--- a/tests/libqos/usb.c
+++ b/tests/libqos/usb.c
@@ -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"
diff --git a/tests/libqos/virtio-mmio.c b/tests/libqos/virtio-mmio.c
index 0cab38f29..a4382f366 100644
--- a/tests/libqos/virtio-mmio.c
+++ b/tests/libqos/virtio-mmio.c
@@ -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,
};
diff --git a/tests/libqos/virtio-pci.c b/tests/libqos/virtio-pci.c
index 18b92b95d..fde2ff0bc 100644
--- a/tests/libqos/virtio-pci.c
+++ b/tests/libqos/virtio-pci.c
@@ -8,6 +8,7 @@
*/
#include "qemu/osdep.h"
+#include <glib.h>
#include "libqtest.h"
#include "libqos/virtio.h"
#include "libqos/virtio-pci.h"
@@ -15,10 +16,7 @@
#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);
}
diff --git a/tests/libqos/virtio-pci.h b/tests/libqos/virtio-pci.h
index efcac2d3d..8f0e52ad4 100644
--- a/tests/libqos/virtio-pci.h
+++ b/tests/libqos/virtio-pci.h
@@ -13,6 +13,23 @@
#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;
diff --git a/tests/libqos/virtio.c b/tests/libqos/virtio.c
index d8c2970de..613decea5 100644
--- a/tests/libqos/virtio.c
+++ b/tests/libqos/virtio.c
@@ -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);
}
diff --git a/tests/libqos/virtio.h b/tests/libqos/virtio.h
index 0250842bf..01012787b 100644
--- a/tests/libqos/virtio.h
+++ b/tests/libqos/virtio.h
@@ -11,19 +11,78 @@
#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,
diff --git a/tests/libqtest.c b/tests/libqtest.c
index eb00f1392..b12a9e4ca 100644
--- a/tests/libqtest.c
+++ b/tests/libqtest.c
@@ -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;
diff --git a/tests/m48t59-test.c b/tests/m48t59-test.c
index 0f921ef38..a751fd350 100644
--- a/tests/m48t59-test.c
+++ b/tests/m48t59-test.c
@@ -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
index 84f37552e..000000000
--- a/tests/migration/.gitignore
+++ /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
index cb150ce80..000000000
--- a/tests/migration/guestperf-batch.py
+++ /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
index d70bb7a55..000000000
--- a/tests/migration/guestperf-plot.py
+++ /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
index 99b027e8b..000000000
--- a/tests/migration/guestperf.py
+++ /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
index e69de29bb..000000000
--- a/tests/migration/guestperf/__init__.py
+++ /dev/null
diff --git a/tests/migration/guestperf/comparison.py b/tests/migration/guestperf/comparison.py
deleted file mode 100644
index d0b7df97c..000000000
--- a/tests/migration/guestperf/comparison.py
+++ /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
index 0a13050bc..000000000
--- a/tests/migration/guestperf/engine.py
+++ /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
index a66c9dd18..000000000
--- a/tests/migration/guestperf/hardware.py
+++ /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
index bc42249e1..000000000
--- a/tests/migration/guestperf/plot.py
+++ /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
index 46d2157b8..000000000
--- a/tests/migration/guestperf/progress.py
+++ /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
index 6a1f97149..000000000
--- a/tests/migration/guestperf/report.py
+++ /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
index 705c2e864..000000000
--- a/tests/migration/guestperf/scenario.py
+++ /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
index 185c5697a..000000000
--- a/tests/migration/guestperf/shell.py
+++ /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
index f94d80989..000000000
--- a/tests/migration/guestperf/timings.py
+++ /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
index cf8ce8b16..000000000
--- a/tests/migration/stress.c
+++ /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();
-}
diff --git a/tests/ne2000-test.c b/tests/ne2000-test.c
index b7cf3dd2f..3727875f2 100644
--- a/tests/ne2000-test.c
+++ b/tests/ne2000-test.c
@@ -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/nvme-test.c b/tests/nvme-test.c
index c8bece443..ec06893ee 100644
--- a/tests/nvme-test.c
+++ b/tests/nvme-test.c
@@ -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/pc-cpu-test.c b/tests/pc-cpu-test.c
index 4428cea5f..6b34ca588 100644
--- a/tests/pc-cpu-test.c
+++ b/tests/pc-cpu-test.c
@@ -8,6 +8,7 @@
*/
#include "qemu/osdep.h"
+#include <glib.h>
#include "qemu-common.h"
#include "libqtest.h"
diff --git a/tests/pcnet-test.c b/tests/pcnet-test.c
index efb1ef44e..2ddf4965c 100644
--- a/tests/pcnet-test.c
+++ b/tests/pcnet-test.c
@@ -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
index 229e9e901..000000000
--- a/tests/postcopy-test.c
+++ /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
index 7a628574c..000000000
--- a/tests/prom-env-test.c
+++ /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();
-}
diff --git a/tests/pvpanic-test.c b/tests/pvpanic-test.c
index 3bfa67866..d435833f7 100644
--- a/tests/pvpanic-test.c
+++ b/tests/pvpanic-test.c
@@ -8,6 +8,7 @@
*/
#include "qemu/osdep.h"
+#include <glib.h>
#include "libqtest.h"
static void test_panic(void)
diff --git a/tests/pxe-test.c b/tests/pxe-test.c
index b2cc355a9..875e4c4a2 100644
--- a/tests/pxe-test.c
+++ b/tests/pxe-test.c
@@ -12,6 +12,7 @@
*/
#include "qemu/osdep.h"
+#include <glib.h>
#include <glib/gstdio.h>
#include "qemu-common.h"
#include "libqtest.h"
diff --git a/tests/q35-test.c b/tests/q35-test.c
index 71538fc17..a105f1078 100644
--- a/tests/q35-test.c
+++ b/tests/q35-test.c
@@ -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
index ad0d41732..000000000
--- a/tests/qapi-schema/args-bad-boxed.err
+++ /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
index d00491fd7..000000000
--- a/tests/qapi-schema/args-bad-boxed.exit
+++ /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
index dea0cd0aa..000000000
--- a/tests/qapi-schema/args-bad-boxed.json
+++ /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
index e69de29bb..000000000
--- a/tests/qapi-schema/args-bad-boxed.out
+++ /dev/null
diff --git a/tests/qapi-schema/args-boxed-anon.err b/tests/qapi-schema/args-boxed-anon.err
deleted file mode 100644
index f24f34521..000000000
--- a/tests/qapi-schema/args-boxed-anon.err
+++ /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
index d00491fd7..000000000
--- a/tests/qapi-schema/args-boxed-anon.exit
+++ /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
index 95f60da2e..000000000
--- a/tests/qapi-schema/args-boxed-anon.json
+++ /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
index e69de29bb..000000000
--- a/tests/qapi-schema/args-boxed-anon.out
+++ /dev/null
diff --git a/tests/qapi-schema/args-boxed-empty.err b/tests/qapi-schema/args-boxed-empty.err
deleted file mode 100644
index 039603e85..000000000
--- a/tests/qapi-schema/args-boxed-empty.err
+++ /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
index d00491fd7..000000000
--- a/tests/qapi-schema/args-boxed-empty.exit
+++ /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
index 52717e065..000000000
--- a/tests/qapi-schema/args-boxed-empty.json
+++ /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
index e69de29bb..000000000
--- a/tests/qapi-schema/args-boxed-empty.out
+++ /dev/null
diff --git a/tests/qapi-schema/args-boxed-string.err b/tests/qapi-schema/args-boxed-string.err
deleted file mode 100644
index d326b48ae..000000000
--- a/tests/qapi-schema/args-boxed-string.err
+++ /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
index d00491fd7..000000000
--- a/tests/qapi-schema/args-boxed-string.exit
+++ /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
index f91a1502e..000000000
--- a/tests/qapi-schema/args-boxed-string.json
+++ /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
index e69de29bb..000000000
--- a/tests/qapi-schema/args-boxed-string.out
+++ /dev/null
diff --git a/tests/qapi-schema/args-union.err b/tests/qapi-schema/args-union.err
index f8ad223dd..1d693d74d 100644
--- a/tests/qapi-schema/args-union.err
+++ b/tests/qapi-schema/args-union.err
@@ -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'
diff --git a/tests/qapi-schema/args-union.json b/tests/qapi-schema/args-union.json
index 2fcaeaae1..7bdcbb7f0 100644
--- a/tests/qapi-schema/args-union.json
+++ b/tests/qapi-schema/args-union.json
@@ -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
index 68ec6f2d2..000000000
--- a/tests/qapi-schema/event-boxed-empty.err
+++ /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
index d00491fd7..000000000
--- a/tests/qapi-schema/event-boxed-empty.exit
+++ /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
index cb145f143..000000000
--- a/tests/qapi-schema/event-boxed-empty.json
+++ /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
index e69de29bb..000000000
--- a/tests/qapi-schema/event-boxed-empty.out
+++ /dev/null
diff --git a/tests/qapi-schema/event-case.out b/tests/qapi-schema/event-case.out
index 5a0f2bf80..b6b4134a8 100644
--- a/tests/qapi-schema/event-case.out
+++ b/tests/qapi-schema/event-case.out
@@ -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
index e826bf078..000000000
--- a/tests/qapi-schema/flat-union-incomplete-branch.err
+++ /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
index d00491fd7..000000000
--- a/tests/qapi-schema/flat-union-incomplete-branch.exit
+++ /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
index 25a411bc8..000000000
--- a/tests/qapi-schema/flat-union-incomplete-branch.json
+++ /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
index e69de29bb..000000000
--- a/tests/qapi-schema/flat-union-incomplete-branch.out
+++ /dev/null
diff --git a/tests/qapi-schema/ident-with-escape.out b/tests/qapi-schema/ident-with-escape.out
index 1d2722c02..382ce2fa2 100644
--- a/tests/qapi-schema/ident-with-escape.out
+++ b/tests/qapi-schema/ident-with-escape.out
@@ -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
diff --git a/tests/qapi-schema/indented-expr.out b/tests/qapi-schema/indented-expr.out
index e8171c935..ae3293a3a 100644
--- a/tests/qapi-schema/indented-expr.out
+++ b/tests/qapi-schema/indented-expr.out
@@ -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
diff --git a/tests/qapi-schema/qapi-schema-test.json b/tests/qapi-schema/qapi-schema-test.json
index 17194637b..f571e1bb3 100644
--- a/tests/qapi-schema/qapi-schema-test.json
+++ b/tests/qapi-schema/qapi-schema-test.json
@@ -127,8 +127,6 @@
{ '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:
@@ -156,8 +154,6 @@
'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
diff --git a/tests/qapi-schema/qapi-schema-test.out b/tests/qapi-schema/qapi-schema-test.out
index 9d99c4eeb..19cd214f6 100644
--- a/tests/qapi-schema/qapi-schema-test.out
+++ b/tests/qapi-schema/qapi-schema-test.out
@@ -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
diff --git a/tests/qapi-schema/test-qapi.py b/tests/qapi-schema/test-qapi.py
index ef74e2c4c..649677e01 100644
--- a/tests/qapi-schema/test-qapi.py
+++ b/tests/qapi-schema/test-qapi.py
@@ -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)
diff --git a/tests/qemu-iotests/004 b/tests/qemu-iotests/004
index 6f2aa3d9a..67e1beb20 100755
--- a/tests/qemu-iotests/004
+++ b/tests/qemu-iotests/004
@@ -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
diff --git a/tests/qemu-iotests/012 b/tests/qemu-iotests/012
index 01a770d59..d1d3f2209 100755
--- a/tests/qemu-iotests/012
+++ b/tests/qemu-iotests/012
@@ -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"
diff --git a/tests/qemu-iotests/023.out b/tests/qemu-iotests/023.out
index 664871b30..d4e9be25e 100644
--- a/tests/qemu-iotests/023.out
+++ b/tests/qemu-iotests/023.out
@@ -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)
@@ -4055,78 +3623,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)
@@ -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)
diff --git a/tests/qemu-iotests/026.out b/tests/qemu-iotests/026.out
index 853173572..d84d82c11 100644
--- a/tests/qemu-iotests/026.out
+++ b/tests/qemu-iotests/026.out
@@ -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.
diff --git a/tests/qemu-iotests/026.out.nocache b/tests/qemu-iotests/026.out.nocache
index 672d77c6e..9c2c8a948 100644
--- a/tests/qemu-iotests/026.out.nocache
+++ b/tests/qemu-iotests/026.out.nocache
@@ -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.
diff --git a/tests/qemu-iotests/034 b/tests/qemu-iotests/034
index 1b28bdae6..c711cfce9 100755
--- a/tests/qemu-iotests/034
+++ b/tests/qemu-iotests/034
@@ -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.
#
diff --git a/tests/qemu-iotests/039.out b/tests/qemu-iotests/039.out
index c6e0ac2da..32c884694 100644
--- a/tests/qemu-iotests/039.out
+++ b/tests/qemu-iotests/039.out
@@ -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.
diff --git a/tests/qemu-iotests/041 b/tests/qemu-iotests/041
index cbf5e0ba5..b1c542f99 100755
--- a/tests/qemu-iotests/041
+++ b/tests/qemu-iotests/041
@@ -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 """
diff --git a/tests/qemu-iotests/048 b/tests/qemu-iotests/048
index 203c04fc7..e1eeac2a3 100755
--- a/tests/qemu-iotests/048
+++ b/tests/qemu-iotests/048
@@ -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
diff --git a/tests/qemu-iotests/048.out b/tests/qemu-iotests/048.out
index 0bcf6635a..57100dc45 100644
--- a/tests/qemu-iotests/048.out
+++ b/tests/qemu-iotests/048.out
@@ -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)
diff --git a/tests/qemu-iotests/052 b/tests/qemu-iotests/052
index 842eaced3..4b647242d 100755
--- a/tests/qemu-iotests/052
+++ b/tests/qemu-iotests/052
@@ -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
diff --git a/tests/qemu-iotests/052.out b/tests/qemu-iotests/052.out
index a377d3028..9dab51c0e 100644
--- a/tests/qemu-iotests/052.out
+++ b/tests/qemu-iotests/052.out
@@ -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)
diff --git a/tests/qemu-iotests/061.out b/tests/qemu-iotests/061.out
index a431b7f30..a03732e19 100644
--- a/tests/qemu-iotests/061.out
+++ b/tests/qemu-iotests/061.out
@@ -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
diff --git a/tests/qemu-iotests/071.out b/tests/qemu-iotests/071.out
index 8c6851e79..2b40eadae 100644
--- a/tests/qemu-iotests/071.out
+++ b/tests/qemu-iotests/071.out
@@ -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
diff --git a/tests/qemu-iotests/077 b/tests/qemu-iotests/077
index d2d2a2d68..4dc680b7f 100755
--- a/tests/qemu-iotests/077
+++ b/tests/qemu-iotests/077
@@ -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
diff --git a/tests/qemu-iotests/077.out b/tests/qemu-iotests/077.out
index 16f951fd3..eab14ae2e 100644
--- a/tests/qemu-iotests/077.out
+++ b/tests/qemu-iotests/077.out
@@ -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
diff --git a/tests/qemu-iotests/083 b/tests/qemu-iotests/083
index bff936004..bc724ae05 100755
--- a/tests/qemu-iotests/083
+++ b/tests/qemu-iotests/083
@@ -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
diff --git a/tests/qemu-iotests/087.out b/tests/qemu-iotests/087.out
index a95c4b0be..055c553cd 100644
--- a/tests/qemu-iotests/087.out
+++ b/tests/qemu-iotests/087.out
@@ -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"}
diff --git a/tests/qemu-iotests/089.out b/tests/qemu-iotests/089.out
index 18f5fdda7..5b541a340 100644
--- a/tests/qemu-iotests/089.out
+++ b/tests/qemu-iotests/089.out
@@ -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 ===
diff --git a/tests/qemu-iotests/095 b/tests/qemu-iotests/095
index 030adb22e..dad04b9ac 100755
--- a/tests/qemu-iotests/095
+++ b/tests/qemu-iotests/095
@@ -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
diff --git a/tests/qemu-iotests/096 b/tests/qemu-iotests/096
index aeeb3753c..e34204b8f 100644
--- a/tests/qemu-iotests/096
+++ b/tests/qemu-iotests/096
@@ -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
index 000000000..5b2fb3333
--- /dev/null
+++ b/tests/qemu-iotests/100
@@ -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
index 000000000..05649038d
--- /dev/null
+++ b/tests/qemu-iotests/100.out
@@ -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
diff --git a/tests/qemu-iotests/109 b/tests/qemu-iotests/109
index 280ed27aa..f980b0c9e 100755
--- a/tests/qemu-iotests/109
+++ b/tests/qemu-iotests/109
@@ -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
diff --git a/tests/qemu-iotests/109.out b/tests/qemu-iotests/109.out
index e5d70d75f..38bc073a3 100644
--- a/tests/qemu-iotests/109.out
+++ b/tests/qemu-iotests/109.out
@@ -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.
diff --git a/tests/qemu-iotests/136 b/tests/qemu-iotests/136
index 635b97755..e8c6937fc 100644
--- a/tests/qemu-iotests/136
+++ b/tests/qemu-iotests/136
@@ -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)
diff --git a/tests/qemu-iotests/136.out b/tests/qemu-iotests/136.out
index cfa5c0d0e..0a5e9583a 100644
--- a/tests/qemu-iotests/136.out
+++ b/tests/qemu-iotests/136.out
@@ -1,5 +1,5 @@
-...................................
+........................................
----------------------------------------------------------------------
-Ran 35 tests
+Ran 40 tests
OK
diff --git a/tests/qemu-iotests/137.out b/tests/qemu-iotests/137.out
index c0e753483..88c702cf7 100644
--- a/tests/qemu-iotests/137.out
+++ b/tests/qemu-iotests/137.out
@@ -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
diff --git a/tests/qemu-iotests/141.out b/tests/qemu-iotests/141.out
index eaf1e603e..adceac181 100644
--- a/tests/qemu-iotests/141.out
+++ b/tests/qemu-iotests/141.out
@@ -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"}}
diff --git a/tests/qemu-iotests/144.out b/tests/qemu-iotests/144.out
index 387855c37..410d74180 100644
--- a/tests/qemu-iotests/144.out
+++ b/tests/qemu-iotests/144.out
@@ -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"}}
diff --git a/tests/qemu-iotests/149 b/tests/qemu-iotests/149
index 84072513d..52e23d294 100755
--- a/tests/qemu-iotests/149
+++ b/tests/qemu-iotests/149
@@ -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 = [
diff --git a/tests/qemu-iotests/149.out b/tests/qemu-iotests/149.out
index 90b5b55ef..287f01301 100644
--- a/tests/qemu-iotests/149.out
+++ b/tests/qemu-iotests/149.out
@@ -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
index 7ca7219f0..000000000
--- a/tests/qemu-iotests/154
+++ /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
index da9eabdda..000000000
--- a/tests/qemu-iotests/154.out
+++ /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
index 4057b5e2a..000000000
--- a/tests/qemu-iotests/155
+++ /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
index 4176bb940..000000000
--- a/tests/qemu-iotests/155.out
+++ /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
index cc95ff1f9..000000000
--- a/tests/qemu-iotests/156
+++ /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
index 3af82ae54..000000000
--- a/tests/qemu-iotests/156.out
+++ /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
index 8d939cb74..000000000
--- a/tests/qemu-iotests/157
+++ /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
index 77a9c03d2..000000000
--- a/tests/qemu-iotests/157.out
+++ /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
index 0b43ea339..000000000
--- a/tests/qemu-iotests/162
+++ /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
index 9bba72353..000000000
--- a/tests/qemu-iotests/162.out
+++ /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
diff --git a/tests/qemu-iotests/README b/tests/qemu-iotests/README
index 6079b401a..4ccfdd1cc 100644
--- a/tests/qemu-iotests/README
+++ b/tests/qemu-iotests/README
@@ -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.
diff --git a/tests/qemu-iotests/common b/tests/qemu-iotests/common
index d60ea2ce3..49e193112 100644
--- a/tests/qemu-iotests/common
+++ b/tests/qemu-iotests/common
@@ -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
diff --git a/tests/qemu-iotests/common.config b/tests/qemu-iotests/common.config
index f6384fbae..f824651ba 100644
--- a/tests/qemu-iotests/common.config
+++ b/tests/qemu-iotests/common.config
@@ -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; }")
diff --git a/tests/qemu-iotests/common.filter b/tests/qemu-iotests/common.filter
index 3ab6e4d76..8a6e1b57c 100644
--- a/tests/qemu-iotests/common.filter
+++ b/tests/qemu-iotests/common.filter
@@ -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" \
diff --git a/tests/qemu-iotests/common.rc b/tests/qemu-iotests/common.rc
index 306b00c21..5249ec592 100644
--- a/tests/qemu-iotests/common.rc
+++ b/tests/qemu-iotests/common.rc
@@ -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'
diff --git a/tests/qemu-iotests/group b/tests/qemu-iotests/group
index 50ddeed80..822953b6f 100644
--- a/tests/qemu-iotests/group
+++ b/tests/qemu-iotests/group
@@ -106,7 +106,7 @@
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
@@ -153,8 +153,3 @@
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
diff --git a/tests/qemu-iotests/iotests.py b/tests/qemu-iotests/iotests.py
index dbe0ee548..56f988ab3 100644
--- a/tests/qemu-iotests/iotests.py
+++ b/tests/qemu-iotests/iotests.py
@@ -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
index 76360a0cf..000000000
--- a/tests/qht-bench.c
+++ /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;
-}
diff --git a/tests/qom-test.c b/tests/qom-test.c
index 23493a2b0..bd5cdde26 100644
--- a/tests/qom-test.c
+++ b/tests/qom-test.c
@@ -8,6 +8,7 @@
*/
#include "qemu/osdep.h"
+#include <glib.h>
#include "qemu-common.h"
#include "qemu/cutils.h"
diff --git a/tests/rcutorture.c b/tests/rcutorture.c
index 4002ecf12..244f0f28b 100644
--- a/tests/rcutorture.c
+++ b/tests/rcutorture.c
@@ -61,6 +61,7 @@
*/
#include "qemu/osdep.h"
+#include <glib.h>
#include "qemu/atomic.h"
#include "qemu/rcu.h"
#include "qemu/thread.h"
diff --git a/tests/rtc-test.c b/tests/rtc-test.c
index a086efd12..fa7029aa8 100644
--- a/tests/rtc-test.c
+++ b/tests/rtc-test.c
@@ -12,6 +12,7 @@
*/
#include "qemu/osdep.h"
+#include <glib.h>
#include "libqtest.h"
#include "hw/timer/mc146818rtc_regs.h"
diff --git a/tests/rtl8139-test.c b/tests/rtl8139-test.c
index 13de7eeaf..54e5aa7d0 100644
--- a/tests/rtl8139-test.c
+++ b/tests/rtl8139-test.c
@@ -8,6 +8,7 @@
*/
#include "qemu/osdep.h"
+#include <glib.h>
#include "libqtest.h"
#include "libqos/pci-pc.h"
#include "qemu/timer.h"
diff --git a/tests/spapr-phb-test.c b/tests/spapr-phb-test.c
index 21004a76e..f53911d9f 100644
--- a/tests/spapr-phb-test.c
+++ b/tests/spapr-phb-test.c
@@ -8,6 +8,7 @@
* See the COPYING file in the top-level directory.
*/
#include "qemu/osdep.h"
+#include <glib.h>
#include "libqtest.h"
diff --git a/tests/tcg/xtensa/linker.ld.S b/tests/tcg/xtensa/linker.ld.S
index 5902302cf..f1e7fa9f8 100644
--- a/tests/tcg/xtensa/linker.ld.S
+++ b/tests/tcg/xtensa/linker.ld.S
@@ -1,4 +1,4 @@
-#include "core-isa.h"
+#include <core-isa.h>
#if XTENSA_HAVE_BE
OUTPUT_FORMAT("elf32-xtensa-be")
diff --git a/tests/tco-test.c b/tests/tco-test.c
index 0d13aa8d6..ac11175e9 100644
--- a/tests/tco-test.c
+++ b/tests/tco-test.c
@@ -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"
diff --git a/tests/test-aio.c b/tests/test-aio.c
index 03aa84697..39b8ce89d 100644
--- a/tests/test-aio.c
+++ b/tests/test-aio.c
@@ -11,6 +11,7 @@
*/
#include "qemu/osdep.h"
+#include <glib.h>
#include "block/aio.h"
#include "qapi/error.h"
#include "qemu/timer.h"
diff --git a/tests/test-base64.c b/tests/test-base64.c
index ec122ceba..922e839dd 100644
--- a/tests/test-base64.c
+++ b/tests/test-base64.c
@@ -19,6 +19,7 @@
*/
#include "qemu/osdep.h"
+#include <glib.h>
#include "qapi/error.h"
#include "qemu/base64.h"
diff --git a/tests/test-bitops.c b/tests/test-bitops.c
index 5a791d2e1..505095060 100644
--- a/tests/test-bitops.c
+++ b/tests/test-bitops.c
@@ -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();
}
diff --git a/tests/test-blockjob-txn.c b/tests/test-blockjob-txn.c
index d049cba8a..55fad9507 100644
--- a/tests/test-blockjob-txn.c
+++ b/tests/test-blockjob-txn.c
@@ -11,10 +11,10 @@
*/
#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
index 5b0e934a0..000000000
--- a/tests/test-blockjob.c
+++ /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
index df0c04551..000000000
--- a/tests/test-clone-visitor.c
+++ /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();
-}
diff --git a/tests/test-coroutine.c b/tests/test-coroutine.c
index ee5e06d32..dd4ced946 100644
--- a/tests/test-coroutine.c
+++ b/tests/test-coroutine.c
@@ -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);
diff --git a/tests/test-crypto-cipher.c b/tests/test-crypto-cipher.c
index 1b5130d5f..66d1c63fd 100644
--- a/tests/test-crypto-cipher.c
+++ b/tests/test-crypto-cipher.c
@@ -19,6 +19,7 @@
*/
#include "qemu/osdep.h"
+#include <glib.h>
#include "crypto/init.h"
#include "crypto/cipher.h"
diff --git a/tests/test-crypto-hash.c b/tests/test-crypto-hash.c
index 42fc77a10..735d6d7e0 100644
--- a/tests/test-crypto-hash.c
+++ b/tests/test-crypto-hash.c
@@ -19,6 +19,7 @@
*/
#include "qemu/osdep.h"
+#include <glib.h>
#include "crypto/init.h"
#include "crypto/hash.h"
@@ -30,56 +31,27 @@
#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);
}
}
diff --git a/tests/test-crypto-secret.c b/tests/test-crypto-secret.c
index 13fc6c4c7..aa26c2049 100644
--- a/tests/test-crypto-secret.c
+++ b/tests/test-crypto-secret.c
@@ -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);
}
diff --git a/tests/test-crypto-xts.c b/tests/test-crypto-xts.c
index 1f1412c45..7f68b063c 100644
--- a/tests/test-crypto-xts.c
+++ b/tests/test-crypto-xts.c
@@ -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);
}
}
diff --git a/tests/test-cutils.c b/tests/test-cutils.c
index 64e3e95ce..fb8f5b532 100644
--- a/tests/test-cutils.c
+++ b/tests/test-cutils.c
@@ -26,6 +26,7 @@
*/
#include "qemu/osdep.h"
+#include <glib.h>
#include "qemu/cutils.h"
diff --git a/tests/test-filter-mirror.c b/tests/test-filter-mirror.c
index ffaaffabd..f60bf2adb 100644
--- a/tests/test-filter-mirror.c
+++ b/tests/test-filter-mirror.c
@@ -9,6 +9,7 @@
*/
#include "qemu/osdep.h"
+#include <glib.h>
#include "libqtest.h"
#include "qemu/iov.h"
#include "qemu/sockets.h"
diff --git a/tests/test-filter-redirector.c b/tests/test-filter-redirector.c
index c63b68f03..b93012cea 100644
--- a/tests/test-filter-redirector.c
+++ b/tests/test-filter-redirector.c
@@ -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;
}
diff --git a/tests/test-hbitmap.c b/tests/test-hbitmap.c
index c0e9895fb..abe142791 100644
--- a/tests/test-hbitmap.c
+++ b/tests/test-hbitmap.c
@@ -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;
}
diff --git a/tests/test-int128.c b/tests/test-int128.c
index 4390123bd..cacf6beac 100644
--- a/tests/test-int128.c
+++ b/tests/test-int128.c
@@ -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
diff --git a/tests/test-io-channel-socket.c b/tests/test-io-channel-socket.c
index f73e063d7..855306b8d 100644
--- a/tests/test-io-channel-socket.c
+++ b/tests/test-io-channel-socket.c
@@ -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);
}
diff --git a/tests/test-io-task.c b/tests/test-io-task.c
index e091c12e1..5a9775086 100644
--- a/tests/test-io-task.c
+++ b/tests/test-io-task.c
@@ -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();
}
diff --git a/tests/test-iov.c b/tests/test-iov.c
index 46ae25efd..3f25268dd 100644
--- a/tests/test-iov.c
+++ b/tests/test-iov.c
@@ -1,4 +1,5 @@
#include "qemu/osdep.h"
+#include <glib.h>
#include "qemu-common.h"
#include "qemu/iov.h"
#include "qemu/sockets.h"
diff --git a/tests/test-logging.c b/tests/test-logging.c
index a12585f70..ac8deedc9 100644
--- a/tests/test-logging.c
+++ b/tests/test-logging.c
@@ -25,17 +25,14 @@
*/
#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();
}
diff --git a/tests/test-mul64.c b/tests/test-mul64.c
index 9be775d08..1282ec5a2 100644
--- a/tests/test-mul64.c
+++ b/tests/test-mul64.c
@@ -7,6 +7,7 @@
*/
#include "qemu/osdep.h"
+#include <glib.h>
#include "qemu/host-utils.h"
diff --git a/tests/test-netfilter.c b/tests/test-netfilter.c
index 8b5a9b21b..7d105c323 100644
--- a/tests/test-netfilter.c
+++ b/tests/test-netfilter.c
@@ -9,6 +9,7 @@
*/
#include "qemu/osdep.h"
+#include <glib.h>
#include "libqtest.h"
/* add a netfilter to a netdev and then remove it */
diff --git a/tests/test-opts-visitor.c b/tests/test-opts-visitor.c
index 0a9e75f1b..008e67738 100644
--- a/tests/test-opts-visitor.c
+++ b/tests/test-opts-visitor.c
@@ -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);
}
diff --git a/tests/test-qdev-global-props.c b/tests/test-qdev-global-props.c
index 48e5b7315..f0cc31e11 100644
--- a/tests/test-qdev-global-props.c
+++ b/tests/test-qdev-global-props.c
@@ -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
index 9541ce31e..000000000
--- a/tests/test-qdist.c
+++ /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();
-}
diff --git a/tests/test-qemu-opts.c b/tests/test-qemu-opts.c
index a505a3e05..32abed5ea 100644
--- a/tests/test-qemu-opts.c
+++ b/tests/test-qemu-opts.c
@@ -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",
diff --git a/tests/test-qga.c b/tests/test-qga.c
index dac8fb8c0..72a89dec2 100644
--- a/tests/test-qga.c
+++ b/tests/test-qga.c
@@ -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
index d8a83caf5..000000000
--- a/tests/test-qht-par.c
+++ /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
index 46a64b673..000000000
--- a/tests/test-qht.c
+++ /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();
-}
diff --git a/tests/test-qmp-commands.c b/tests/test-qmp-commands.c
index 261fd9e31..14a9ebbd5 100644
--- a/tests/test-qmp-commands.c
+++ b/tests/test-qmp-commands.c
@@ -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);
diff --git a/tests/test-qmp-event.c b/tests/test-qmp-event.c
index 633dc8740..a296fdbac 100644
--- a/tests/test-qmp-event.c
+++ b/tests/test-qmp-event.c
@@ -12,6 +12,7 @@
*/
#include "qemu/osdep.h"
+#include <glib.h>
#include "qemu-common.h"
#include "test-qapi-types.h"
diff --git a/tests/test-qmp-input-strict.c b/tests/test-qmp-input-strict.c
index 814550ac7..d71727e27 100644
--- a/tests/test-qmp-input-strict.c
+++ b/tests/test-qmp-input-strict.c
@@ -12,6 +12,7 @@
*/
#include "qemu/osdep.h"
+#include <glib.h>
#include "qemu-common.h"
#include "qapi/error.h"
@@ -19,14 +20,13 @@
#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,
diff --git a/tests/test-qmp-input-visitor.c b/tests/test-qmp-input-visitor.c
index f583dce3e..852328375 100644
--- a/tests/test-qmp-input-visitor.c
+++ b/tests/test-qmp-input-visitor.c
@@ -11,6 +11,7 @@
*/
#include "qemu/osdep.h"
+#include <glib.h>
#include "qemu-common.h"
#include "qapi/error.h"
@@ -18,11 +19,10 @@
#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",
diff --git a/tests/test-qmp-output-visitor.c b/tests/test-qmp-output-visitor.c
index 513d71f0d..c70926793 100644
--- a/tests/test-qmp-output-visitor.c
+++ b/tests/test-qmp-output-visitor.c
@@ -11,6 +11,7 @@
*/
#include "qemu/osdep.h"
+#include <glib.h>
#include "qemu-common.h"
#include "qapi/error.h"
@@ -18,40 +19,28 @@
#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);
diff --git a/tests/test-rcu-list.c b/tests/test-rcu-list.c
index 1514d7ec9..79d375014 100644
--- a/tests/test-rcu-list.c
+++ b/tests/test-rcu-list.c
@@ -21,6 +21,7 @@
*/
#include "qemu/osdep.h"
+#include <glib.h>
#include "qemu/atomic.h"
#include "qemu/rcu.h"
#include "qemu/thread.h"
diff --git a/tests/test-rfifolock.c b/tests/test-rfifolock.c
index 471a81114..9a3cb243b 100644
--- a/tests/test-rfifolock.c
+++ b/tests/test-rfifolock.c
@@ -11,6 +11,7 @@
*/
#include "qemu/osdep.h"
+#include <glib.h>
#include "qemu-common.h"
#include "qemu/rfifolock.h"
diff --git a/tests/test-string-input-visitor.c b/tests/test-string-input-visitor.c
index d837ebeda..9e6906a56 100644
--- a/tests/test-string-input-visitor.c
+++ b/tests/test-string-input-visitor.c
@@ -11,6 +11,7 @@
*/
#include "qemu/osdep.h"
+#include <glib.h>
#include "qemu-common.h"
#include "qapi/error.h"
@@ -20,15 +21,15 @@
#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 */
diff --git a/tests/test-string-output-visitor.c b/tests/test-string-output-visitor.c
index 444844a15..1ecd75b85 100644
--- a/tests/test-string-output-visitor.c
+++ b/tests/test-string-output-visitor.c
@@ -11,6 +11,7 @@
*/
#include "qemu/osdep.h"
+#include <glib.h>
#include "qemu-common.h"
#include "qapi/error.h"
@@ -20,53 +21,39 @@
#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);
}
}
diff --git a/tests/test-thread-pool.c b/tests/test-thread-pool.c
index 8dbf66a44..88dc7316b 100644
--- a/tests/test-thread-pool.c
+++ b/tests/test-thread-pool.c
@@ -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. */
diff --git a/tests/test-throttle.c b/tests/test-throttle.c
index 363b59a38..744a52436 100644
--- a/tests/test-throttle.c
+++ b/tests/test-throttle.c
@@ -13,13 +13,13 @@
*/
#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);
diff --git a/tests/test-timed-average.c b/tests/test-timed-average.c
index e2bcf5fe1..1cc4ab302 100644
--- a/tests/test-timed-average.c
+++ b/tests/test-timed-average.c
@@ -11,6 +11,7 @@
*/
#include "qemu/osdep.h"
+#include <glib.h>
#include "qemu/timed-average.h"
diff --git a/tests/test-visitor-serialization.c b/tests/test-visitor-serialization.c
index dba467076..9adbc30a4 100644
--- a/tests/test-visitor-serialization.c
+++ b/tests/test-visitor-serialization.c
@@ -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);
}
diff --git a/tests/test-vmstate.c b/tests/test-vmstate.c
index 41fd841ae..713d4443b 100644
--- a/tests/test-vmstate.c
+++ b/tests/test-vmstate.c
@@ -23,12 +23,12 @@
*/
#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);
diff --git a/tests/test-write-threshold.c b/tests/test-write-threshold.c
index 97ca12f71..fdbc8020f 100644
--- a/tests/test-write-threshold.c
+++ b/tests/test-write-threshold.c
@@ -7,6 +7,7 @@
*/
#include "qemu/osdep.h"
+#include <glib.h>
#include "block/block_int.h"
#include "block/write-threshold.h"
diff --git a/tests/test-x86-cpuid.c b/tests/test-x86-cpuid.c
index ff225006e..8eb0bc6ad 100644
--- a/tests/test-x86-cpuid.c
+++ b/tests/test-x86-cpuid.c
@@ -23,6 +23,7 @@
*/
#include "qemu/osdep.h"
+#include <glib.h>
#include "hw/i386/topology.h"
diff --git a/tests/tmp105-test.c b/tests/tmp105-test.c
index a7940a463..235cae013 100644
--- a/tests/tmp105-test.c
+++ b/tests/tmp105-test.c
@@ -8,6 +8,7 @@
*/
#include "qemu/osdep.h"
+#include <glib.h>
#include "libqtest.h"
#include "libqos/i2c.h"
diff --git a/tests/tpci200-test.c b/tests/tpci200-test.c
index 0321ec27e..cb2b00ca8 100644
--- a/tests/tpci200-test.c
+++ b/tests/tpci200-test.c
@@ -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/usb-hcd-ehci-test.c b/tests/usb-hcd-ehci-test.c
index eb247ad45..a0f13ef40 100644
--- a/tests/usb-hcd-ehci-test.c
+++ b/tests/usb-hcd-ehci-test.c
@@ -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"
diff --git a/tests/usb-hcd-ohci-test.c b/tests/usb-hcd-ohci-test.c
index 4758813d7..efd6669c7 100644
--- a/tests/usb-hcd-ohci-test.c
+++ b/tests/usb-hcd-ohci-test.c
@@ -8,6 +8,7 @@
*/
#include "qemu/osdep.h"
+#include <glib.h>
#include "libqtest.h"
#include "libqos/usb.h"
diff --git a/tests/usb-hcd-uhci-test.c b/tests/usb-hcd-uhci-test.c
index 5cd59ad91..71ff2ea18 100644
--- a/tests/usb-hcd-uhci-test.c
+++ b/tests/usb-hcd-uhci-test.c
@@ -8,6 +8,7 @@
*/
#include "qemu/osdep.h"
+#include <glib.h>
#include "libqtest.h"
#include "libqos/usb.h"
#include "hw/usb/uhci-regs.h"
diff --git a/tests/usb-hcd-xhci-test.c b/tests/usb-hcd-xhci-test.c
index 22513e9eb..7e2e212df 100644
--- a/tests/usb-hcd-xhci-test.c
+++ b/tests/usb-hcd-xhci-test.c
@@ -8,6 +8,7 @@
*/
#include "qemu/osdep.h"
+#include <glib.h>
#include "libqtest.h"
#include "libqos/usb.h"
diff --git a/tests/vhost-user-bridge.c b/tests/vhost-user-bridge.c
index 775e03106..0779ba260 100644
--- a/tests/vhost-user-bridge.c
+++ b/tests/vhost-user-bridge.c
@@ -33,9 +33,12 @@
#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;
}
diff --git a/tests/vhost-user-test.c b/tests/vhost-user-test.c
index 27b10c19b..69615968c 100644
--- a/tests/vhost-user-test.c
+++ b/tests/vhost-user-test.c
@@ -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();
diff --git a/tests/virtio-9p-test.c b/tests/virtio-9p-test.c
index 1e39335a7..59d0f1fa9 100644
--- a/tests/virtio-9p-test.c
+++ b/tests/virtio-9p-test.c
@@ -8,6 +8,7 @@
*/
#include "qemu/osdep.h"
+#include <glib.h>
#include "libqtest.h"
#include "qemu-common.h"
diff --git a/tests/virtio-balloon-test.c b/tests/virtio-balloon-test.c
index 0d0046bf2..b010ce98e 100644
--- a/tests/virtio-balloon-test.c
+++ b/tests/virtio-balloon-test.c
@@ -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/virtio-blk-test.c b/tests/virtio-blk-test.c
index 811cf756c..3a66630d7 100644
--- a/tests/virtio-blk-test.c
+++ b/tests/virtio-blk-test.c
@@ -9,6 +9,7 @@
*/
#include "qemu/osdep.h"
+#include <glib.h>
#include "libqtest.h"
#include "libqos/virtio.h"
#include "libqos/virtio-pci.h"
@@ -18,11 +19,25 @@
#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;
}
diff --git a/tests/virtio-console-test.c b/tests/virtio-console-test.c
index 1c3de072f..0b9c2a55e 100644
--- a/tests/virtio-console-test.c
+++ b/tests/virtio-console-test.c
@@ -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;
}
diff --git a/tests/virtio-net-test.c b/tests/virtio-net-test.c
index 361506faf..04cfcd594 100644
--- a/tests/virtio-net-test.c
+++ b/tests/virtio-net-test.c
@@ -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;
}
diff --git a/tests/virtio-rng-test.c b/tests/virtio-rng-test.c
index e1b26401f..771dbd73a 100644
--- a/tests/virtio-rng-test.c
+++ b/tests/virtio-rng-test.c
@@ -8,6 +8,7 @@
*/
#include "qemu/osdep.h"
+#include <glib.h>
#include "libqtest.h"
#include "libqos/pci.h"
diff --git a/tests/virtio-scsi-test.c b/tests/virtio-scsi-test.c
index f1489e68a..d78747a46 100644
--- a/tests/virtio-scsi-test.c
+++ b/tests/virtio-scsi-test.c
@@ -9,6 +9,7 @@
*/
#include "qemu/osdep.h"
+#include <glib.h>
#include "libqtest.h"
#include "block/scsi.h"
#include "libqos/virtio.h"
@@ -17,13 +18,11 @@
#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;
}
diff --git a/tests/virtio-serial-test.c b/tests/virtio-serial-test.c
index b14d943ad..480d4abb2 100644
--- a/tests/virtio-serial-test.c
+++ b/tests/virtio-serial-test.c
@@ -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/vmxnet3-test.c b/tests/vmxnet3-test.c
index 159c0ad72..6ef0e2f04 100644
--- a/tests/vmxnet3-test.c
+++ b/tests/vmxnet3-test.c
@@ -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/wdt_ib700-test.c b/tests/wdt_ib700-test.c
index 49f4f0c22..efe337045 100644
--- a/tests/wdt_ib700-test.c
+++ b/tests/wdt_ib700-test.c
@@ -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;
}
diff --git a/thread-pool.c b/thread-pool.c
index 6fba91352..03ba0b02a 100644
--- a/thread-pool.c
+++ b/thread-pool.c
@@ -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 2dac36666..f057d86d9 100644
--- 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)
{
diff --git a/trace-events b/trace-events
index 616cc5237..835074387 100644
--- a/trace-events
+++ b/trace-events
@@ -25,11 +25,117 @@
#
# 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
diff --git a/trace/Makefile.objs b/trace/Makefile.objs
index 4d91b3b83..5145b34d1 100644
--- a/trace/Makefile.objs
+++ b/trace/Makefile.objs
@@ -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
diff --git a/trace/control-internal.h b/trace/control-internal.h
index a4e5f4aa0..dcf67f505 100644
--- a/trace/control-internal.h
+++ b/trace/control-internal.h
@@ -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.
@@ -10,13 +10,10 @@
#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
index 74c029acc..000000000
--- a/trace/control-target.c
+++ /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]--;
- }
- }
-}
diff --git a/trace/control.c b/trace/control.c
index d173c09f4..d099f735d 100644
--- a/trace/control.c
+++ b/trace/control.c
@@ -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.
@@ -19,41 +19,11 @@
#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);
- }
- }
-}
diff --git a/trace/control.h b/trace/control.h
index 0413b2876..e2ba6d4de 100644
--- a/trace/control.h
+++ b/trace/control.h
@@ -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 */
diff --git a/trace/event-internal.h b/trace/event-internal.h
index 5d8fa97ca..86f6a511b 100644
--- a/trace/event-internal.h
+++ b/trace/event-internal.h
@@ -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.
*
@@ -24,10 +23,9 @@
*/
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 */
diff --git a/trace/ftrace.h b/trace/ftrace.h
index cb5e35d21..92372e3ca 100644
--- a/trace/ftrace.h
+++ b/trace/ftrace.h
@@ -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
index ddda93425..000000000
--- a/trace/mem-internal.h
+++ /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
index 9c88bcb4e..000000000
--- a/trace/mem.h
+++ /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 */
diff --git a/trace/qmp.c b/trace/qmp.c
index 11d2564e7..8aa2660aa 100644
--- a/trace/qmp.c
+++ b/trace/qmp.c
@@ -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.
@@ -12,153 +12,63 @@
#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);
}
}
diff --git a/translate-all.c b/translate-all.c
index 0dd6466e0..8329ea60e 100644
--- a/translate-all.c
+++ b/translate-all.c
@@ -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"
@@ -71,12 +72,11 @@
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;
diff --git a/translate-all.h b/translate-all.h
index ba8e4d63c..038464005 100644
--- a/translate-all.h
+++ b/translate-all.h
@@ -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 */
diff --git a/translate-common.c b/translate-common.c
index 5e989cdf7..ffbfe856c 100644
--- a/translate-common.c
+++ b/translate-common.c
@@ -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;
diff --git a/ui/console-gl.c b/ui/console-gl.c
index 5165e2164..74b1bed6e 100644
--- a/ui/console-gl.c
+++ b/ui/console-gl.c
@@ -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;
diff --git a/ui/console.c b/ui/console.c
index c24bfe422..bf385790b 100644
--- a/ui/console.c
+++ b/ui/console.c
@@ -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);
}
diff --git a/ui/curses_keys.h b/ui/curses_keys.h
index e39ef9e71..f7467449b 100644
--- a/ui/curses_keys.h
+++ b/ui/curses_keys.h
@@ -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"
diff --git a/ui/cursor.c b/ui/cursor.c
index 5155b392e..a276e01f1 100644
--- a/ui/cursor.c
+++ b/ui/cursor.c
@@ -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)
diff --git a/ui/egl-helpers.c b/ui/egl-helpers.c
index 79cee0503..558edfdeb 100644
--- a/ui/egl-helpers.c
+++ b/ui/egl-helpers.c
@@ -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;
}
diff --git a/ui/gtk-egl.c b/ui/gtk-egl.c
index 3f5d328c7..431457c74 100644
--- a/ui/gtk-egl.c
+++ b/ui/gtk-egl.c
@@ -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)
{
diff --git a/ui/gtk-gl-area.c b/ui/gtk-gl-area.c
index 0df5a36a9..b86ff3cbe 100644
--- a/ui/gtk-gl-area.c
+++ b/ui/gtk-gl-area.c
@@ -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)
{
diff --git a/ui/gtk.c b/ui/gtk.c
index 58d20eed6..9876d899a 100644
--- 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)
diff --git a/ui/input-linux.c b/ui/input-linux.c
index 0e230ce69..1d33b5c12 100644
--- a/ui/input-linux.c
+++ b/ui/input-linux.c
@@ -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;
diff --git a/ui/keymaps.h b/ui/keymaps.h
index 47d061343..a7600d575 100644
--- a/ui/keymaps.h
+++ b/ui/keymaps.h
@@ -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__ */
diff --git a/ui/qemu-pixman.c b/ui/qemu-pixman.c
index 6e8b83add..c9f8dce7f 100644
--- a/ui/qemu-pixman.c
+++ b/ui/qemu-pixman.c
@@ -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)
diff --git a/ui/sdl2-2d.c b/ui/sdl2-2d.c
index 8ab68d67b..95930061e 100644
--- a/ui/sdl2-2d.c
+++ b/ui/sdl2-2d.c
@@ -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();
}
diff --git a/ui/sdl2-gl.c b/ui/sdl2-gl.c
index 039645df3..a324ecaca 100644
--- a/ui/sdl2-gl.c
+++ b/ui/sdl2-gl.c
@@ -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)
{
diff --git a/ui/sdl_zoom.c b/ui/sdl_zoom.c
index b96196bac..72622c264 100644
--- a/ui/sdl_zoom.c
+++ b/ui/sdl_zoom.c
@@ -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);
diff --git a/ui/sdl_zoom.h b/ui/sdl_zoom.h
index 39696ddb0..74955bc94 100644
--- a/ui/sdl_zoom.h
+++ b/ui/sdl_zoom.h
@@ -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 */
diff --git a/ui/shader.c b/ui/shader.c
index 1ffddbef3..9264009b8 100644
--- a/ui/shader.c
+++ b/ui/shader.c
@@ -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;
diff --git a/ui/spice-display.c b/ui/spice-display.c
index 99132b69b..2a77a545a 100644
--- a/ui/spice-display.c
+++ b/ui/spice-display.c
@@ -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
index 93fe5482e..000000000
--- a/ui/trace-events
+++ /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"
diff --git a/ui/vnc-auth-sasl.h b/ui/vnc-auth-sasl.h
index cb42745a6..3f59da67e 100644
--- a/ui/vnc-auth-sasl.h
+++ b/ui/vnc-auth-sasl.h
@@ -22,8 +22,10 @@
* 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__ */
+
diff --git a/ui/vnc-auth-vencrypt.h b/ui/vnc-auth-vencrypt.h
index 1e3540666..9f674c517 100644
--- a/ui/vnc-auth-vencrypt.h
+++ b/ui/vnc-auth-vencrypt.h
@@ -24,9 +24,10 @@
* 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__ */
diff --git a/ui/vnc-enc-tight.c b/ui/vnc-enc-tight.c
index 49df85e76..e5cba0e5a 100644
--- a/ui/vnc-enc-tight.c
+++ b/ui/vnc-enc-tight.c
@@ -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;
}
diff --git a/ui/vnc-enc-tight.h b/ui/vnc-enc-tight.h
index 95c3dac02..a3add788e 100644
--- a/ui/vnc-enc-tight.h
+++ b/ui/vnc-enc-tight.h
@@ -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.
@@ -180,4 +180,4 @@
#define VNC_TIGHT_DETECT_MIN_WIDTH 8
#define VNC_TIGHT_DETECT_MIN_HEIGHT 8
-#endif /* VNC_ENC_TIGHT_H */
+#endif /* VNC_ENCODING_TIGHT_H */
diff --git a/ui/vnc-enc-zrle.h b/ui/vnc-enc-zrle.h
index 6535cb2aa..6b182132a 100644
--- a/ui/vnc-enc-zrle.h
+++ b/ui/vnc-enc-zrle.h
@@ -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
diff --git a/ui/vnc-enc-zywrle.h b/ui/vnc-enc-zywrle.h
index 610bd79d1..d436d588f 100644
--- a/ui/vnc-enc-zywrle.h
+++ b/ui/vnc-enc-zywrle.h
@@ -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
diff --git a/ui/vnc-palette.c b/ui/vnc-palette.c
index dc7c0ba99..3b89d1af2 100644
--- a/ui/vnc-palette.c
+++ b/ui/vnc-palette.c
@@ -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)
diff --git a/ui/vnc-ws.c b/ui/vnc-ws.c
index 3bac46e77..7c79a4c37 100644
--- a/ui/vnc-ws.c
+++ b/ui/vnc-ws.c
@@ -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,
diff --git a/ui/vnc-ws.h b/ui/vnc-ws.h
index 396cacfcb..652b6fc39 100644
--- a/ui/vnc-ws.h
+++ b/ui/vnc-ws.h
@@ -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 */
diff --git a/ui/vnc.c b/ui/vnc.c
index d1087c93a..3e89dad8f 100644
--- 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;
diff --git a/ui/vnc.h b/ui/vnc.h
index ab5f24411..81a326116 100644
--- 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 */
diff --git a/user-exec.c b/user-exec.c
index 95f9f97c5..d8d597baf 100644
--- a/user-exec.c
+++ b/user-exec.c
@@ -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"
@@ -40,14 +39,43 @@
//#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
diff --git a/util/Makefile.objs b/util/Makefile.objs
index 96cb1e0e5..a8a777ec4 100644
--- a/util/Makefile.objs
+++ b/util/Makefile.objs
@@ -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
diff --git a/util/acl.c b/util/acl.c
index c105addad..723b6a89b 100644
--- a/util/acl.c
+++ b/util/acl.c
@@ -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:
+ */
diff --git a/util/buffer.c b/util/buffer.c
index d8bb87453..a6118bf5b 100644
--- a/util/buffer.c
+++ b/util/buffer.c
@@ -19,14 +19,13 @@
*/
#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);
}
diff --git a/util/coroutine-gthread.c b/util/coroutine-gthread.c
index 62bfb4015..fb697eb0b 100644
--- a/util/coroutine-gthread.c
+++ b/util/coroutine-gthread.c
@@ -19,6 +19,7 @@
*/
#include "qemu/osdep.h"
+#include <glib.h>
#include "qemu-common.h"
#include "qemu/coroutine_int.h"
diff --git a/util/cutils.c b/util/cutils.c
index 7505fdaa8..43d1afbbe 100644
--- a/util/cutils.c
+++ b/util/cutils.c
@@ -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>
diff --git a/util/error.c b/util/error.c
index 9c40b1f45..cae251173 100644
--- a/util/error.c
+++ b/util/error.c
@@ -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;
}
diff --git a/util/hbitmap.c b/util/hbitmap.c
index 99fd2ba37..b22b87d0a 100644
--- a/util/hbitmap.c
+++ b/util/hbitmap.c
@@ -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;
}
diff --git a/util/iov.c b/util/iov.c
index 74e6ca8ed..003fcce66 100644
--- a/util/iov.c
+++ b/util/iov.c
@@ -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;
diff --git a/util/log.c b/util/log.c
index 54b54e868..1857730dc 100644
--- a/util/log.c
+++ b/util/log.c
@@ -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",
diff --git a/util/memfd.c b/util/memfd.c
index 4571d1aba..7c406914c 100644
--- a/util/memfd.c
+++ b/util/memfd.c
@@ -27,8 +27,11 @@
#include "qemu/osdep.h"
+#include <glib.h>
#include <glib/gprintf.h>
+#include <sys/mman.h>
+
#include "qemu/memfd.h"
#ifdef CONFIG_MEMFD
diff --git a/util/mmap-alloc.c b/util/mmap-alloc.c
index 5a85aa3c8..0b4cc7f7f 100644
--- a/util/mmap-alloc.c
+++ b/util/mmap-alloc.c
@@ -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
diff --git a/util/module.c b/util/module.c
index 86e3f7aba..ce058aef6 100644
--- a/util/module.c
+++ b/util/module.c
@@ -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)
diff --git a/util/osdep.c b/util/osdep.c
index 06fb1cfda..d56d07111 100644
--- a/util/osdep.c
+++ b/util/osdep.c
@@ -25,6 +25,10 @@
/* 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);
diff --git a/util/oslib-posix.c b/util/oslib-posix.c
index f2d4e9e59..4adde93ac 100644
--- a/util/oslib-posix.c
+++ b/util/oslib-posix.c
@@ -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);
}
diff --git a/util/oslib-win32.c b/util/oslib-win32.c
index 4c1dcf1e6..c926db4a5 100644
--- a/util/oslib-win32.c
+++ b/util/oslib-win32.c
@@ -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
index 5f75e24c2..000000000
--- a/util/qdist.c
+++ /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);
-}
diff --git a/util/qemu-coroutine-io.c b/util/qemu-coroutine-io.c
index 44a8969a6..91b9357d4 100644
--- a/util/qemu-coroutine-io.c
+++ b/util/qemu-coroutine-io.c
@@ -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)
diff --git a/util/qemu-coroutine-lock.c b/util/qemu-coroutine-lock.c
index 22aa9abb3..da37ca7f9 100644
--- a/util/qemu-coroutine-lock.c
+++ b/util/qemu-coroutine-lock.c
@@ -31,13 +31,13 @@
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)
diff --git a/util/qemu-coroutine-sleep.c b/util/qemu-coroutine-sleep.c
index 25de3ed3d..6966831d3 100644
--- a/util/qemu-coroutine-sleep.c
+++ b/util/qemu-coroutine-sleep.c
@@ -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,
diff --git a/util/qemu-coroutine.c b/util/qemu-coroutine.c
index 89f21a9ce..5816702cc 100644
--- a/util/qemu-coroutine.c
+++ b/util/qemu-coroutine.c
@@ -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);
diff --git a/util/qemu-sockets.c b/util/qemu-sockets.c
index 2aed799e9..0d536911c 100644
--- a/util/qemu-sockets.c
+++ b/util/qemu-sockets.c
@@ -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
index 16a8d7950..000000000
--- a/util/qht.c
+++ /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
index 416df7cda..000000000
--- a/util/range.c
+++ /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;
-}
diff --git a/util/rfifolock.c b/util/rfifolock.c
index 084c2f0ea..c22f5feee 100644
--- a/util/rfifolock.c
+++ b/util/rfifolock.c
@@ -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);
}
diff --git a/util/throttle.c b/util/throttle.c
index 3817d9b90..71246b234 100644
--- a/util/throttle.c
+++ b/util/throttle.c
@@ -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
index 747e6baf7..000000000
--- a/util/trace-events
+++ /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
diff --git a/util/uri.c b/util/uri.c
index 70a9cbcbd..d109d6c01 100644
--- a/util/uri.c
+++ b/util/uri.c
@@ -52,6 +52,7 @@
*/
#include "qemu/osdep.h"
+#include <glib.h>
#include "qemu/uri.h"
diff --git a/vl.c b/vl.c
index b3c80d507..5db5dc288 100644
--- 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;
}
diff --git a/xen-hvm.c b/xen-hvm.c
index 2f348edf8..039680a6d 100644
--- 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;
diff --git a/xen-mapcache.c b/xen-mapcache.c
index 8f3a59201..49f394a77 100644
--- a/xen-mapcache.c
+++ b/xen-mapcache.c
@@ -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"