aboutsummaryrefslogtreecommitdiff
path: root/tests
diff options
context:
space:
mode:
Diffstat (limited to 'tests')
-rw-r--r--tests/Makefile.include129
-rw-r--r--tests/ac97-test.c47
-rw-r--r--tests/ahci-test.c6
-rw-r--r--tests/check-qdict.c2
-rw-r--r--tests/data/qobject/qdict.txt4999
-rw-r--r--tests/drive_del-test.c25
-rw-r--r--tests/e1000-test.c64
-rw-r--r--tests/e1000e-test.c358
-rw-r--r--tests/eepro100-test.c65
-rw-r--r--tests/es1370-test.c46
-rw-r--r--tests/i440fx-test.c2
-rw-r--r--tests/ide-test.c19
-rw-r--r--tests/ipoctal232-test.c35
-rw-r--r--tests/ivshmem-test.c4
-rw-r--r--tests/libqos/aarch64-xlnx-zcu102-machine.c94
-rw-r--r--tests/libqos/ahci.c2
-rw-r--r--tests/libqos/arm-raspi2-machine.c91
-rw-r--r--tests/libqos/arm-sabrelite-machine.c91
-rw-r--r--tests/libqos/arm-smdkc210-machine.c91
-rw-r--r--tests/libqos/arm-virt-machine.c90
-rw-r--r--tests/libqos/arm-xilinx-zynq-a9-machine.c94
-rw-r--r--tests/libqos/e1000e.c260
-rw-r--r--tests/libqos/e1000e.h53
-rw-r--r--tests/libqos/libqos-pc.c5
-rw-r--r--tests/libqos/libqos-spapr.c5
-rw-r--r--tests/libqos/libqos.c13
-rw-r--r--tests/libqos/libqos.h13
-rw-r--r--tests/libqos/malloc-generic.c39
-rw-r--r--tests/libqos/malloc-generic.h21
-rw-r--r--tests/libqos/malloc-pc.c22
-rw-r--r--tests/libqos/malloc-pc.h4
-rw-r--r--tests/libqos/malloc-spapr.c19
-rw-r--r--tests/libqos/malloc-spapr.h4
-rw-r--r--tests/libqos/malloc.c42
-rw-r--r--tests/libqos/malloc.h21
-rw-r--r--tests/libqos/pci-pc.c86
-rw-r--r--tests/libqos/pci-pc.h29
-rw-r--r--tests/libqos/pci-spapr.c119
-rw-r--r--tests/libqos/pci-spapr.h26
-rw-r--r--tests/libqos/pci.c46
-rw-r--r--tests/libqos/pci.h16
-rw-r--r--tests/libqos/ppc64_pseries-machine.c111
-rw-r--r--tests/libqos/qgraph.c753
-rw-r--r--tests/libqos/qgraph.h575
-rw-r--r--tests/libqos/qgraph_internal.h257
-rw-r--r--tests/libqos/sdhci.c163
-rw-r--r--tests/libqos/sdhci.h70
-rw-r--r--tests/libqos/tpci200.c65
-rw-r--r--tests/libqos/virtio-9p.c173
-rw-r--r--tests/libqos/virtio-9p.h42
-rw-r--r--tests/libqos/virtio-balloon.c113
-rw-r--r--tests/libqos/virtio-balloon.h39
-rw-r--r--tests/libqos/virtio-blk.c124
-rw-r--r--tests/libqos/virtio-blk.h40
-rw-r--r--tests/libqos/virtio-mmio.c116
-rw-r--r--tests/libqos/virtio-mmio.h6
-rw-r--r--tests/libqos/virtio-net.c195
-rw-r--r--tests/libqos/virtio-net.h41
-rw-r--r--tests/libqos/virtio-pci.c187
-rw-r--r--tests/libqos/virtio-pci.h18
-rw-r--r--tests/libqos/virtio-rng.c110
-rw-r--r--tests/libqos/virtio-rng.h39
-rw-r--r--tests/libqos/virtio-scsi.c117
-rw-r--r--tests/libqos/virtio-scsi.h39
-rw-r--r--tests/libqos/virtio-serial.c110
-rw-r--r--tests/libqos/virtio-serial.h39
-rw-r--r--tests/libqos/virtio.c24
-rw-r--r--tests/libqos/virtio.h11
-rw-r--r--tests/libqos/x86_64_pc-machine.c114
-rw-r--r--tests/libqtest.h6
-rw-r--r--tests/m48t59-test.c4
-rw-r--r--tests/megasas-test.c80
-rw-r--r--tests/migration-test.c4
-rw-r--r--tests/ne2000-test.c46
-rw-r--r--tests/nvme-test.c78
-rw-r--r--tests/pci-test.c25
-rw-r--r--tests/pcnet-test.c46
-rw-r--r--tests/q35-test.c4
-rw-r--r--tests/qos-test.c445
-rw-r--r--tests/rtas-test.c2
-rw-r--r--tests/rtc-test.c4
-rw-r--r--tests/rtl8139-test.c8
-rw-r--r--tests/sdhci-test.c185
-rw-r--r--tests/spapr-phb-test.c32
-rw-r--r--tests/tco-test.c2
-rw-r--r--tests/test-aio-multithread.c8
-rw-r--r--tests/test-char.c102
-rw-r--r--tests/test-coroutine.c10
-rw-r--r--tests/test-qgraph.c434
-rw-r--r--tests/tpci200-test.c31
-rw-r--r--tests/usb-hcd-ehci-test.c2
-rw-r--r--tests/usb-hcd-ohci-test.c54
-rw-r--r--tests/vhost-user-test.c398
-rw-r--r--tests/virtio-9p-test.c220
-rw-r--r--tests/virtio-balloon-test.c33
-rw-r--r--tests/virtio-blk-test.c471
-rw-r--r--tests/virtio-console-test.c38
-rw-r--r--tests/virtio-net-test.c226
-rw-r--r--tests/virtio-rng-test.c27
-rw-r--r--tests/virtio-scsi-test.c145
-rw-r--r--tests/virtio-serial-test.c27
-rw-r--r--tests/virtio-test.c25
-rw-r--r--tests/vmxnet3-test.c46
103 files changed, 11908 insertions, 2248 deletions
diff --git a/tests/Makefile.include b/tests/Makefile.include
index 45a4302103..a5719551dd 100644
--- a/tests/Makefile.include
+++ b/tests/Makefile.include
@@ -151,37 +151,10 @@ check-qtest-generic-y += tests/qmp-cmd-test$(EXESUF)
check-qtest-generic-y += tests/device-introspect-test$(EXESUF)
check-qtest-generic-y += tests/cdrom-test$(EXESUF)
-check-qtest-ipack-y += tests/ipoctal232-test$(EXESUF)
-
-check-qtest-virtioserial-$(CONFIG_VIRTIO_SERIAL) += tests/virtio-console-test$(EXESUF)
-
-check-qtest-virtio-$(CONFIG_VIRTIO_NET) += tests/virtio-net-test$(EXESUF)
-check-qtest-virtio-$(CONFIG_VIRTIO_BALLOON) += tests/virtio-balloon-test$(EXESUF)
-check-qtest-virtio-$(CONFIG_VIRTIO_BLK) += tests/virtio-blk-test$(EXESUF)
-check-qtest-virtio-$(CONFIG_VIRTIO_RNG) += tests/virtio-rng-test$(EXESUF)
-check-qtest-virtio-$(CONFIG_VIRTIO_SCSI) += tests/virtio-scsi-test$(EXESUF)
-ifeq ($(CONFIG_VIRTIO)$(CONFIG_VIRTFS)$(CONFIG_PCI),yyy)
-check-qtest-virtio-$(CONFIG_VIRTIO_9P) += tests/virtio-9p-test$(EXESUF)
-endif
-check-qtest-virtio-$(CONFIG_VIRTIO_SERIAL) += tests/virtio-serial-test$(EXESUF)
-check-qtest-virtio-y += $(check-qtest-virtioserial-y)
-
-check-qtest-pci-y += tests/e1000-test$(EXESUF)
-check-qtest-pci-y += tests/e1000e-test$(EXESUF)
check-qtest-pci-$(CONFIG_RTL8139_PCI) += tests/rtl8139-test$(EXESUF)
-check-qtest-pci-$(CONFIG_PCNET_PCI) += tests/pcnet-test$(EXESUF)
-check-qtest-pci-$(CONFIG_EEPRO100_PCI) += tests/eepro100-test$(EXESUF)
-check-qtest-pci-$(CONFIG_NE2000_PCI) += tests/ne2000-test$(EXESUF)
-check-qtest-pci-$(CONFIG_NVME_PCI) += tests/nvme-test$(EXESUF)
-check-qtest-pci-$(CONFIG_AC97) += tests/ac97-test$(EXESUF)
-check-qtest-pci-$(CONFIG_ES1370) += tests/es1370-test$(EXESUF)
-check-qtest-pci-$(CONFIG_VIRTIO) += $(check-qtest-virtio-y)
-check-qtest-pci-$(CONFIG_IPACK) += tests/tpci200-test$(EXESUF)
-check-qtest-pci-$(CONFIG_IPACK) += $(check-qtest-ipack-y)
check-qtest-pci-$(CONFIG_VGA) += tests/display-vga-test$(EXESUF)
check-qtest-pci-$(CONFIG_HDA) += tests/intel-hda-test$(EXESUF)
check-qtest-pci-$(CONFIG_IVSHMEM_DEVICE) += tests/ivshmem-test$(EXESUF)
-check-qtest-pci-$(CONFIG_MEGASAS_SCSI_PCI) += tests/megasas-test$(EXESUF)
check-qtest-i386-$(CONFIG_ISA_TESTDEV) = tests/endianness-test$(EXESUF)
check-qtest-i386-y += tests/fdc-test$(EXESUF)
@@ -203,11 +176,9 @@ check-qtest-i386-y += tests/drive_del-test$(EXESUF)
check-qtest-i386-$(CONFIG_WDT_IB700) += tests/wdt_ib700-test$(EXESUF)
check-qtest-i386-y += tests/tco-test$(EXESUF)
check-qtest-i386-y += $(check-qtest-pci-y)
-check-qtest-i386-$(CONFIG_VMXNET3_PCI) += tests/vmxnet3-test$(EXESUF)
check-qtest-i386-$(CONFIG_PVPANIC) += tests/pvpanic-test$(EXESUF)
check-qtest-i386-$(CONFIG_I82801B11) += tests/i82801b11-test$(EXESUF)
check-qtest-i386-$(CONFIG_IOH3420) += tests/ioh3420-test$(EXESUF)
-check-qtest-i386-$(CONFIG_USB_OHCI) += tests/usb-hcd-ohci-test$(EXESUF)
check-qtest-i386-$(CONFIG_USB_UHCI) += tests/usb-hcd-uhci-test$(EXESUF)
ifeq ($(CONFIG_USB_ECHI)$(CONFIG_USB_UHCI),yy)
check-qtest-i386-y += tests/usb-hcd-ehci-test$(EXESUF)
@@ -216,7 +187,6 @@ check-qtest-i386-$(CONFIG_USB_XHCI_NEC) += tests/usb-hcd-xhci-test$(EXESUF)
check-qtest-i386-y += tests/cpu-plug-test$(EXESUF)
check-qtest-i386-y += tests/q35-test$(EXESUF)
check-qtest-i386-y += tests/vmgenid-test$(EXESUF)
-check-qtest-i386-$(CONFIG_VHOST_NET_USER) += tests/vhost-user-test$(EXESUF)
check-qtest-i386-$(CONFIG_TPM_CRB) += tests/tpm-crb-swtpm-test$(EXESUF)
check-qtest-i386-$(CONFIG_TPM_CRB) += tests/tpm-crb-test$(EXESUF)
check-qtest-i386-$(CONFIG_TPM_TIS) += tests/tpm-tis-swtpm-test$(EXESUF)
@@ -229,7 +199,6 @@ check-qtest-i386-y += tests/test-announce-self$(EXESUF)
check-qtest-i386-y += tests/test-x86-cpuid-compat$(EXESUF)
check-qtest-i386-y += tests/numa-test$(EXESUF)
check-qtest-x86_64-y += $(check-qtest-i386-y)
-check-qtest-x86_64-$(CONFIG_SDHCI) += tests/sdhci-test$(EXESUF)
check-qtest-alpha-y += tests/boot-serial-test$(EXESUF)
check-qtest-alpha-$(CONFIG_VGA) += tests/display-vga-test$(EXESUF)
@@ -260,17 +229,14 @@ check-qtest-ppc-y += tests/boot-serial-test$(EXESUF)
check-qtest-ppc-$(CONFIG_M48T59) += tests/m48t59-test$(EXESUF)
check-qtest-ppc64-y += $(check-qtest-ppc-y)
-check-qtest-ppc64-$(CONFIG_PSERIES) += tests/spapr-phb-test$(EXESUF)
check-qtest-ppc64-$(CONFIG_PSERIES) += tests/device-plug-test$(EXESUF)
check-qtest-ppc64-$(CONFIG_POWERNV) += tests/pnv-xscom-test$(EXESUF)
check-qtest-ppc64-y += tests/migration-test$(EXESUF)
check-qtest-ppc64-y += tests/test-announce-self$(EXESUF)
check-qtest-ppc64-$(CONFIG_PSERIES) += tests/rtas-test$(EXESUF)
check-qtest-ppc64-$(CONFIG_SLIRP) += tests/pxe-test$(EXESUF)
-check-qtest-ppc64-$(CONFIG_USB_OHCI) += tests/usb-hcd-ohci-test$(EXESUF)
check-qtest-ppc64-$(CONFIG_USB_UHCI) += tests/usb-hcd-uhci-test$(EXESUF)
check-qtest-ppc64-$(CONFIG_USB_XHCI_NEC) += tests/usb-hcd-xhci-test$(EXESUF)
-check-qtest-ppc64-$(CONFIG_VIRTIO) += $(check-qtest-virtio-y)
check-qtest-ppc64-$(CONFIG_SLIRP) += tests/test-netfilter$(EXESUF)
check-qtest-ppc64-$(CONFIG_POSIX) += tests/test-filter-mirror$(EXESUF)
check-qtest-ppc64-$(CONFIG_RTL8139_PCI) += tests/test-filter-redirector$(EXESUF)
@@ -296,14 +262,11 @@ check-qtest-arm-y += tests/pca9552-test$(EXESUF)
check-qtest-arm-y += tests/ds1338-test$(EXESUF)
check-qtest-arm-y += tests/microbit-test$(EXESUF)
check-qtest-arm-y += tests/m25p80-test$(EXESUF)
-check-qtest-arm-$(CONFIG_VIRTIO_BLK) += tests/virtio-blk-test$(EXESUF)
check-qtest-arm-y += tests/test-arm-mptimer$(EXESUF)
check-qtest-arm-y += tests/boot-serial-test$(EXESUF)
-check-qtest-arm-$(CONFIG_SDHCI) += tests/sdhci-test$(EXESUF)
check-qtest-arm-y += tests/hexloader-test$(EXESUF)
check-qtest-aarch64-y = tests/numa-test$(EXESUF)
-check-qtest-aarch64-$(CONFIG_SDHCI) += tests/sdhci-test$(EXESUF)
check-qtest-aarch64-y += tests/boot-serial-test$(EXESUF)
check-qtest-aarch64-y += tests/migration-test$(EXESUF)
@@ -732,7 +695,10 @@ tests/test-crypto-ivgen$(EXESUF): tests/test-crypto-ivgen.o $(test-crypto-obj-y)
tests/test-crypto-afsplit$(EXESUF): tests/test-crypto-afsplit.o $(test-crypto-obj-y)
tests/test-crypto-block$(EXESUF): tests/test-crypto-block.o $(test-crypto-obj-y)
-libqos-obj-y = tests/libqos/pci.o tests/libqos/fw_cfg.o tests/libqos/malloc.o
+libqgraph-obj-y = tests/libqos/qgraph.o
+
+libqos-obj-y = $(libqgraph-obj-y) tests/libqos/pci.o tests/libqos/fw_cfg.o
+libqos-obj-y += tests/libqos/malloc.o
libqos-obj-y += tests/libqos/i2c.o tests/libqos/libqos.o
libqos-spapr-obj-y = $(libqos-obj-y) tests/libqos/malloc-spapr.o
libqos-spapr-obj-y += tests/libqos/libqos-spapr.o
@@ -744,7 +710,64 @@ libqos-pc-obj-y += tests/libqos/ahci.o
libqos-omap-obj-y = $(libqos-obj-y) tests/libqos/i2c-omap.o
libqos-imx-obj-y = $(libqos-obj-y) tests/libqos/i2c-imx.o
libqos-usb-obj-y = $(libqos-spapr-obj-y) $(libqos-pc-obj-y) tests/libqos/usb.o
-libqos-virtio-obj-y = $(libqos-spapr-obj-y) $(libqos-pc-obj-y) tests/libqos/virtio.o tests/libqos/virtio-pci.o tests/libqos/virtio-mmio.o tests/libqos/malloc-generic.o
+
+# Devices
+qos-test-obj-y = tests/qos-test.o $(libqgraph-obj-y)
+qos-test-obj-y += $(libqos-pc-obj-y) $(libqos-spapr-obj-y)
+qos-test-obj-y += tests/libqos/e1000e.o
+qos-test-obj-y += tests/libqos/sdhci.o
+qos-test-obj-y += tests/libqos/tpci200.o
+qos-test-obj-y += tests/libqos/virtio.o
+qos-test-obj-$(CONFIG_VIRTFS) += tests/libqos/virtio-9p.o
+qos-test-obj-y += tests/libqos/virtio-balloon.o
+qos-test-obj-y += tests/libqos/virtio-blk.o
+qos-test-obj-y += tests/libqos/virtio-mmio.o
+qos-test-obj-y += tests/libqos/virtio-net.o
+qos-test-obj-y += tests/libqos/virtio-pci.o
+qos-test-obj-y += tests/libqos/virtio-rng.o
+qos-test-obj-y += tests/libqos/virtio-scsi.o
+qos-test-obj-y += tests/libqos/virtio-serial.o
+
+# Machines
+qos-test-obj-y += tests/libqos/aarch64-xlnx-zcu102-machine.o
+qos-test-obj-y += tests/libqos/arm-raspi2-machine.o
+qos-test-obj-y += tests/libqos/arm-sabrelite-machine.o
+qos-test-obj-y += tests/libqos/arm-smdkc210-machine.o
+qos-test-obj-y += tests/libqos/arm-virt-machine.o
+qos-test-obj-y += tests/libqos/arm-xilinx-zynq-a9-machine.o
+qos-test-obj-y += tests/libqos/ppc64_pseries-machine.o
+qos-test-obj-y += tests/libqos/x86_64_pc-machine.o
+
+# Tests
+qos-test-obj-y += tests/ac97-test.o
+qos-test-obj-y += tests/e1000-test.o
+qos-test-obj-y += tests/e1000e-test.o
+qos-test-obj-y += tests/eepro100-test.o
+qos-test-obj-y += tests/es1370-test.o
+qos-test-obj-y += tests/ipoctal232-test.o
+qos-test-obj-y += tests/megasas-test.o
+qos-test-obj-y += tests/ne2000-test.o
+qos-test-obj-y += tests/nvme-test.o
+qos-test-obj-y += tests/pci-test.o
+qos-test-obj-y += tests/pcnet-test.o
+qos-test-obj-y += tests/sdhci-test.o
+qos-test-obj-y += tests/spapr-phb-test.o
+qos-test-obj-y += tests/usb-hcd-ohci-test.o $(libqos-usb-obj-y)
+qos-test-obj-$(CONFIG_VHOST_NET_USER) += tests/vhost-user-test.o $(chardev-obj-y) $(test-io-obj-y)
+qos-test-obj-y += tests/virtio-test.o
+qos-test-obj-$(CONFIG_VIRTFS) += tests/virtio-9p-test.o
+qos-test-obj-y += tests/virtio-blk-test.o
+qos-test-obj-y += tests/virtio-net-test.o
+qos-test-obj-y += tests/virtio-rng-test.o
+qos-test-obj-y += tests/virtio-scsi-test.o
+qos-test-obj-y += tests/virtio-serial-test.o
+qos-test-obj-y += tests/vmxnet3-test.o
+
+check-unit-y += tests/test-qgraph$(EXESUF)
+tests/test-qgraph$(EXESUF): tests/test-qgraph.o $(libqgraph-obj-y)
+
+check-qtest-generic-y += tests/qos-test$(EXESUF)
+tests/qos-test$(EXESUF): $(qos-test-obj-y)
tests/qmp-test$(EXESUF): tests/qmp-test.o
tests/qmp-cmd-test$(EXESUF): tests/qmp-cmd-test.o
@@ -753,7 +776,6 @@ tests/rtc-test$(EXESUF): tests/rtc-test.o
tests/m48t59-test$(EXESUF): tests/m48t59-test.o
tests/hexloader-test$(EXESUF): tests/hexloader-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/rtas-test$(EXESUF): tests/rtas-test.o $(libqos-spapr-obj-y)
tests/fdc-test$(EXESUF): tests/fdc-test.o
@@ -775,50 +797,27 @@ tests/m25p80-test$(EXESUF): tests/m25p80-test.o
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/pnv-xscom-test$(EXESUF): tests/pnv-xscom-test.o
-tests/eepro100-test$(EXESUF): tests/eepro100-test.o
-tests/vmxnet3-test$(EXESUF): tests/vmxnet3-test.o
-tests/ne2000-test$(EXESUF): tests/ne2000-test.o
tests/wdt_ib700-test$(EXESUF): tests/wdt_ib700-test.o
tests/tco-test$(EXESUF): tests/tco-test.o $(libqos-pc-obj-y)
-tests/virtio-balloon-test$(EXESUF): tests/virtio-balloon-test.o $(libqos-virtio-obj-y)
-tests/virtio-blk-test$(EXESUF): tests/virtio-blk-test.o $(libqos-virtio-obj-y)
tests/virtio-ccw-test$(EXESUF): tests/virtio-ccw-test.o
-tests/virtio-net-test$(EXESUF): tests/virtio-net-test.o $(libqos-pc-obj-y) $(libqos-virtio-obj-y)
-tests/virtio-rng-test$(EXESUF): tests/virtio-rng-test.o $(libqos-pc-obj-y)
-tests/virtio-scsi-test$(EXESUF): tests/virtio-scsi-test.o $(libqos-virtio-obj-y)
-tests/virtio-9p-test$(EXESUF): tests/virtio-9p-test.o $(libqos-virtio-obj-y)
-tests/virtio-serial-test$(EXESUF): tests/virtio-serial-test.o $(libqos-virtio-obj-y)
-tests/virtio-console-test$(EXESUF): tests/virtio-console-test.o $(libqos-virtio-obj-y)
-tests/tpci200-test$(EXESUF): tests/tpci200-test.o
tests/display-vga-test$(EXESUF): tests/display-vga-test.o
-tests/ipoctal232-test$(EXESUF): tests/ipoctal232-test.o
tests/qom-test$(EXESUF): tests/qom-test.o
tests/test-hmp$(EXESUF): tests/test-hmp.o
tests/machine-none-test$(EXESUF): tests/machine-none-test.o
tests/device-plug-test$(EXESUF): tests/device-plug-test.o
-tests/drive_del-test$(EXESUF): tests/drive_del-test.o $(libqos-virtio-obj-y)
-tests/nvme-test$(EXESUF): tests/nvme-test.o $(libqos-pc-obj-y)
+tests/drive_del-test$(EXESUF): tests/drive_del-test.o
tests/pvpanic-test$(EXESUF): tests/pvpanic-test.o
tests/i82801b11-test$(EXESUF): tests/i82801b11-test.o
-tests/ac97-test$(EXESUF): tests/ac97-test.o
-tests/es1370-test$(EXESUF): tests/es1370-test.o
tests/intel-hda-test$(EXESUF): tests/intel-hda-test.o
tests/ioh3420-test$(EXESUF): tests/ioh3420-test.o
-tests/usb-hcd-ohci-test$(EXESUF): tests/usb-hcd-ohci-test.o $(libqos-usb-obj-y)
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/cpu-plug-test$(EXESUF): tests/cpu-plug-test.o
tests/migration-test$(EXESUF): tests/migration-test.o
tests/test-announce-self$(EXESUF): tests/test-announce-self.o
-tests/vhost-user-test$(EXESUF): tests/vhost-user-test.o $(test-util-obj-y) \
- $(qtest-obj-y) $(test-io-obj-y) $(libqos-virtio-obj-y) $(libqos-pc-obj-y) \
- $(chardev-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)
tests/test-keyval$(EXESUF): tests/test-keyval.o $(test-util-obj-y) $(test-qapi-obj-y)
@@ -828,14 +827,12 @@ tests/test-filter-mirror$(EXESUF): tests/test-filter-mirror.o $(qtest-obj-y)
tests/test-filter-redirector$(EXESUF): tests/test-filter-redirector.o $(qtest-obj-y)
tests/test-x86-cpuid-compat$(EXESUF): tests/test-x86-cpuid-compat.o $(qtest-obj-y)
tests/ivshmem-test$(EXESUF): tests/ivshmem-test.o contrib/ivshmem-server/ivshmem-server.o $(libqos-pc-obj-y) $(libqos-spapr-obj-y)
-tests/megasas-test$(EXESUF): tests/megasas-test.o $(libqos-spapr-obj-y) $(libqos-pc-obj-y)
tests/vhost-user-bridge$(EXESUF): tests/vhost-user-bridge.o $(test-util-obj-y) libvhost-user.a
tests/test-uuid$(EXESUF): tests/test-uuid.o $(test-util-obj-y)
tests/test-arm-mptimer$(EXESUF): tests/test-arm-mptimer.o
tests/test-qapi-util$(EXESUF): tests/test-qapi-util.o $(test-util-obj-y)
tests/numa-test$(EXESUF): tests/numa-test.o
tests/vmgenid-test$(EXESUF): tests/vmgenid-test.o tests/boot-sector.o tests/acpi-utils.o
-tests/sdhci-test$(EXESUF): tests/sdhci-test.o $(libqos-pc-obj-y)
tests/cdrom-test$(EXESUF): tests/cdrom-test.o tests/boot-sector.o $(libqos-obj-y)
tests/migration/stress$(EXESUF): tests/migration/stress.o
diff --git a/tests/ac97-test.c b/tests/ac97-test.c
index e0d177bd9c..532fb1cc98 100644
--- a/tests/ac97-test.c
+++ b/tests/ac97-test.c
@@ -9,23 +9,48 @@
#include "qemu/osdep.h"
#include "libqtest.h"
+#include "libqos/qgraph.h"
+#include "libqos/pci.h"
-/* Tests only initialization so far. TODO: Replace with functional tests */
-static void nop(void)
+typedef struct QAC97 QAC97;
+
+struct QAC97 {
+ QOSGraphObject obj;
+ QPCIDevice dev;
+};
+
+static void *ac97_get_driver(void *obj, const char *interface)
{
+ QAC97 *ac97 = obj;
+
+ if (!g_strcmp0(interface, "pci-device")) {
+ return &ac97->dev;
+ }
+
+ fprintf(stderr, "%s not present in e1000e\n", interface);
+ g_assert_not_reached();
}
-int main(int argc, char **argv)
+static void *ac97_create(void *pci_bus, QGuestAllocator *alloc, void *addr)
{
- int ret;
+ QAC97 *ac97 = g_new0(QAC97, 1);
+ QPCIBus *bus = pci_bus;
- g_test_init(&argc, &argv, NULL);
- qtest_add_func("/ac97/nop", nop);
-
- qtest_start("-device AC97");
- ret = g_test_run();
+ qpci_device_init(&ac97->dev, bus, addr);
+ ac97->obj.get_driver = ac97_get_driver;
+ return &ac97->obj;
+}
- qtest_end();
+static void ac97_register_nodes(void)
+{
+ QOSGraphEdgeOptions opts = {
+ .extra_device_opts = "addr=04.0",
+ };
+ add_qpci_address(&opts, &(QPCIAddress) { .devfn = QPCI_DEVFN(4, 0) });
- return ret;
+ qos_node_create_driver("AC97", ac97_create);
+ qos_node_produces("AC97", "pci-device");
+ qos_node_consumes("AC97", "pci-bus", &opts);
}
+
+libqos_init(ac97_register_nodes);
diff --git a/tests/ahci-test.c b/tests/ahci-test.c
index 5dd380e5ea..9f07e6f2ce 100644
--- a/tests/ahci-test.c
+++ b/tests/ahci-test.c
@@ -162,7 +162,7 @@ static AHCIQState *ahci_vboot(const char *cli, va_list ap)
s = g_new0(AHCIQState, 1);
s->parent = qtest_pc_vboot(cli, ap);
global_qtest = s->parent->qts;
- alloc_set_flags(s->parent->alloc, ALLOC_LEAK_ASSERT);
+ alloc_set_flags(&s->parent->alloc, ALLOC_LEAK_ASSERT);
/* Verify that we have an AHCI device present. */
s->dev = get_ahci_device(s->parent->qts, &s->fingerprint);
@@ -1039,7 +1039,7 @@ static void test_dma_fragmented(void)
generate_pattern(tx, bufsize, AHCI_SECTOR_SIZE);
/* Create a DMA buffer in guest memory, and write our pattern to it. */
- ptr = guest_alloc(ahci->parent->alloc, bufsize);
+ ptr = guest_alloc(&ahci->parent->alloc, bufsize);
g_assert(ptr);
bufwrite(ptr, tx, bufsize);
@@ -1059,7 +1059,7 @@ static void test_dma_fragmented(void)
/* Read back the guest's receive buffer into local memory */
bufread(ptr, rx, bufsize);
- guest_free(ahci->parent->alloc, ptr);
+ guest_free(&ahci->parent->alloc, ptr);
g_assert_cmphex(memcmp(tx, rx, bufsize), ==, 0);
diff --git a/tests/check-qdict.c b/tests/check-qdict.c
index a1e8305066..b5efa859b0 100644
--- a/tests/check-qdict.c
+++ b/tests/check-qdict.c
@@ -291,7 +291,7 @@ static void qdict_stress_test(void)
FILE *test_file;
QDict *qdict;
QString *value;
- const char *test_file_path = "qdict-test-data.txt";
+ const char *test_file_path = "tests/data/qobject/qdict.txt";
test_file = fopen(test_file_path, "r");
g_assert(test_file != NULL);
diff --git a/tests/data/qobject/qdict.txt b/tests/data/qobject/qdict.txt
new file mode 100644
index 0000000000..122fda4524
--- /dev/null
+++ b/tests/data/qobject/qdict.txt
@@ -0,0 +1,4999 @@
+00-INDEX: 333
+07: 4096
+1040.bin.ihex: 92633
+11d.c: 17874
+11d.h: 2386
+1200.bin.ihex: 14717
+12160.bin.ihex: 77829
+1232ea962bbaf0e909365f4964f6cceb2ba8ce: 298
+1280.bin.ihex: 88220
+15562512ca6cf14c1b8f08e09d5907118deaf0: 297
+17: 4096
+1d: 4096
+1.Intro: 14968
+21142.c: 8591
+21285.c: 11721
+2860_main_dev.c: 33854
+2860_rtmp_init.c: 26170
+2870_main_dev.c: 39352
+2870_rtmp_init.c: 51247
+2.Process: 22356
+300vtbl.h: 43771
+310vtbl.h: 59655
+3270.ChangeLog: 1889
+3270.txt: 10964
+3550.bin.ihex: 13916
+3780i.c: 21485
+3780i.h: 14180
+38C0800.bin.ihex: 14772
+38C1600.bin.ihex: 17504
+3C359.bin.ihex: 69044
+3c359.c: 60161
+3c359.h: 7264
+3c359.txt: 2463
+3c501.c: 23869
+3c501.h: 2623
+3c503.c: 22491
+3c503.h: 3880
+3c505.c: 48605
+3c505.h: 6535
+3c505.txt: 1831
+3c507.c: 28758
+3c509.c: 42879
+3c509.txt: 9006
+3c515.c: 49671
+3c523.c: 39251
+3c523.h: 11169
+3c527.c: 43065
+3c527.h: 1482
+3c574_cs.c: 35859
+3c589_cs.c: 30110
+3c59x.c: 103272
+3CCFEM556.cis.ihex: 469
+3com: 4096
+3CXEM556.cis.ihex: 463
+3.Early-stage: 9993
+3w-9xxx.c: 77318
+3w-9xxx.h: 26357
+3w-xxxx.c: 85227
+3w-xxxx.h: 16846
+40x: 4096
+40x_mmu.c: 4082
+42: 4096
+44x: 4096
+44x.c: 3615
+44x_emulate.c: 4512
+44x.h: 448
+44x_mmu.c: 2966
+44x_tlb.c: 13997
+44x_tlb.h: 2465
+4.Coding: 20212
+4level-fixup.h: 1028
+4xx: 4096
+4xx.c: 16297
+4xx.h: 1174
+512x: 4096
+5206: 4096
+5206e: 4096
+520x: 4096
+523x: 4096
+5249: 4096
+5272: 4096
+527x: 4096
+528x: 4096
+52xx: 4096
+5307: 4096
+532x: 4096
+53c700.c: 71188
+53c700_d.h_shipped: 28887
+53c700.h: 16652
+53c700.scr: 10894
+53c700.txt: 5042
+5407: 4096
+57xx_iscsi_constants.h: 7004
+57xx_iscsi_hsi.h: 36895
+5d: 4096
+5.Posting: 15211
+66b00c9dc3e1e071bde0ebfeadc40bbc1e8316: 298
+68328: 4096
+68328fb.c: 13570
+68328serial.c: 35841
+68328serial.h: 6237
+68360: 4096
+68360serial.c: 76262
+68EZ328: 4096
+68VZ328: 4096
+6c5e45fe4f1c83df9429b7c2668b41446baac2: 297
+6.Followthrough: 11745
+6pack.c: 24715
+6pack.txt: 7940
+6xx-suspend.S: 1086
+712_defconfig: 25531
+7206: 4096
+73: 4096
+7343: 4096
+770x: 4096
+7721: 4096
+7722: 4096
+7724: 4096
+7751: 4096
+7780: 4096
+7990.c: 22036
+7990.h: 10421
+7.AdvancedTopics: 9648
+7c: 4096
+7segled.c: 2698
+802: 4096
+80211core: 4096
+80211hdr.h: 12326
+80211mgr.c: 28179
+80211mgr.h: 23006
+8021q: 4096
+8139cp.c: 56138
+8139too.c: 71384
+8250_accent.c: 1071
+8250_acorn.c: 3194
+8250_boca.c: 1301
+8250.c: 83003
+8250_early.c: 6636
+8250_exar_st16c554.c: 1191
+8250_fourport.c: 1216
+8250_gsc.c: 3620
+8250.h: 2432
+8250_hp300.c: 7797
+8250_hub6.c: 1224
+8250_mca.c: 1375
+8250_pci.c: 93521
+8250_pci.h: 999
+8250-platform.c: 1091
+8250_pnp.c: 14783
+8253.h: 10999
+8253pit.h: 48
+8255.c: 10692
+8255.h: 1805
+82571.c: 48377
+82596.c: 41209
+82xx: 4096
+8390.c: 2094
+8390.h: 9629
+8390p.c: 2248
+83xx: 4096
+83xx-512x-pci.txt: 1323
+85xx: 4096
+86xx: 4096
+87: 4096
+8b: 4096
+8.Conclusion: 3137
+8xx: 4096
+8xx_immap.h: 14089
+8xxx_gpio.txt: 1343
+941a7798a5169ee0dd69a9e8d5c40ceb702023: 298
+9600.bin.ihex: 14715
+9p: 4096
+9p.h: 13443
+9p.txt: 5113
+a100u2w.c: 36919
+a100u2w.h: 16936
+a2065.c: 20730
+a2065.h: 5135
+a2091.c: 6445
+a2091.h: 1712
+a20.c: 3548
+a20r.c: 5261
+a3000.c: 6528
+a3000.h: 1807
+a3d.c: 11335
+a4000t.c: 3579
+a500_defconfig: 31440
+a800.c: 5950
+aachba.c: 84424
+aaci.c: 27297
+aaci.h: 7022
+aacraid: 4096
+aacraid.h: 53671
+aacraid.txt: 6849
+aaec2000.h: 8936
+aaed2000.c: 2298
+aaed2000.h: 1354
+aaed2000_kbd.c: 5059
+aarp.c: 25379
+ab3100-core.c: 22600
+ab3100.h: 3510
+abdac.c: 15469
+ABI: 4096
+abi.h: 782
+abituguru: 3731
+abituguru3: 2493
+abituguru3.c: 41974
+abituguru.c: 53440
+abituguru-datasheet: 12294
+abi.txt: 1413
+ABI.txt: 1413
+ablkcipher.c: 9484
+abort-ev4.S: 882
+abort-ev4t.S: 913
+abort-ev5tj.S: 987
+abort-ev5t.S: 912
+abort-ev6.S: 1320
+abort-ev7.S: 774
+abort-lv4t.S: 6546
+abort-macro.S: 1144
+abort-nommu.S: 462
+abs_addr.h: 1800
+abspath.c: 2808
+abs.S: 238
+abyss.c: 11197
+abyss.h: 1550
+ac3200.c: 11838
+ac97: 4096
+ac97_bus.c: 1681
+ac97.c: 4489
+ac97c.c: 26095
+ac97c.h: 2045
+ac97_codec.c: 36925
+ac97_codec.h: 15115
+ac97.h: 507
+ac97_id.h: 2422
+ac97_local.h: 1689
+ac97_patch.c: 128568
+ac97_patch.h: 4386
+ac97_pcm.c: 21244
+ac97_proc.c: 18243
+acadia_defconfig: 23272
+acadia.dts: 5188
+ac.c: 9202
+accel.c: 8625
+accel.h: 5627
+access.c: 10521
+accessibility: 4096
+access_ok.h: 1305
+accommon.h: 2825
+acconfig.h: 7688
+accounting: 4096
+acct.c: 17700
+acct.h: 5949
+acdebug.h: 6836
+acdispat.h: 10988
+acecad.c: 7982
+acenic: 4096
+acenic.c: 88166
+acenic.h: 16029
+acenv.h: 11821
+acerhdf.c: 14909
+acer-wmi.c: 30530
+acer-wmi.txt: 6480
+acevents.h: 6692
+acexcep.h: 12764
+acgcc.h: 2843
+acglobal.h: 14485
+achware.h: 4355
+acinterp.h: 16329
+ackvec.c: 12985
+ackvec.h: 3426
+acl7225b.c: 3794
+acl.c: 5321
+acl.h: 1548
+aclinux.h: 5049
+aclocal.h: 34614
+acmacros.h: 22966
+acm.txt: 4974
+acnames.h: 3482
+acnamesp.h: 10211
+acobject.h: 16573
+acopcode.h: 22365
+acorn.c: 12206
+acornfb.c: 35783
+acornfb.h: 4809
+acorn.h: 623
+acornscsi.c: 87770
+acornscsi.h: 9694
+acornscsi-io.S: 3320
+acoutput.h: 10925
+acparser.h: 7436
+acpi: 4096
+acpi_bus.h: 11195
+acpi.c: 6529
+acpica: 12288
+acpi-cpufreq.c: 21588
+acpi_drivers.h: 5322
+acpi-ext.c: 2774
+acpi-ext.h: 590
+acpi.h: 4768
+acpi_memhotplug.c: 14832
+acpi_numa.h: 471
+acpiosxf.h: 7880
+acpi_pcihp.c: 14898
+acpiphp_core.c: 10949
+acpiphp_glue.c: 44065
+acpiphp.h: 6325
+acpiphp_ibm.c: 14740
+acpi_pm.c: 6723
+acpi_pmtmr.h: 672
+acpi-processor.c: 1893
+acpixf.h: 12045
+acpredef.h: 18909
+acquirewdt.c: 8920
+acresrc.h: 11064
+acrestyp.h: 11267
+acs5k_defconfig: 28786
+acs5k_tiny_defconfig: 21413
+acstruct.h: 7738
+act2000: 4096
+act2000.h: 6271
+act2000_isa.c: 11978
+act2000_isa.h: 7615
+act200l-sir.c: 7142
+actables.h: 3945
+act_api.c: 23712
+act_api.h: 4195
+actbl1.h: 35761
+actbl.h: 15492
+act_gact.c: 5493
+action.c: 40
+action.h: 40
+act_ipt.c: 7564
+actisys-sir.c: 7692
+active_mm.txt: 3805
+act_mirred.c: 6285
+act_nat.c: 7265
+act_pedit.c: 6148
+act_police.c: 9833
+act_simple.c: 5238
+act_skbedit.c: 5510
+actypes.h: 34263
+acutils.h: 16898
+acx.c: 16590
+acx.h: 33552
+ad1816a: 4096
+ad1816a.c: 8825
+ad1816a.h: 5363
+ad1816a_lib.c: 30656
+ad1843.c: 16402
+ad1843.h: 1516
+ad1848: 4096
+ad1848.c: 75959
+ad1848.h: 982
+ad1848_mixer.h: 10957
+ad1889.c: 27048
+ad1889.h: 8073
+ad1980.c: 8427
+ad1980.h: 468
+ad73311.c: 2765
+ad73311.h: 2404
+ad7414.c: 7164
+ad7418.c: 8304
+ad7877.c: 20856
+ad7877.h: 796
+ad7879.c: 19019
+ad7879.h: 1004
+adaptec: 4096
+adapter.h: 400
+adb.c: 19706
+adb.h: 2770
+adbhid.c: 35627
+adb-iop.c: 6325
+adb_iop.h: 1081
+adc.c: 8573
+adc.h: 886
+ADC-LH7-Touchscreen: 2187
+adcxx.c: 8256
+adder875.c: 3142
+adder875_defconfig: 21956
+adder875-redboot.dts: 4102
+adder875-uboot.dts: 4072
+addi_amcc_S5920.c: 7563
+addi_amcc_S5920.h: 1016
+addi_amcc_s5933.h: 13296
+addi_apci_035.c: 128
+addi_apci_1032.c: 63
+addi_apci_1500.c: 63
+addi_apci_1516.c: 63
+addi_apci_1564.c: 63
+addi_apci_16xx.c: 63
+addi_apci_1710.c: 63
+addi_apci_2016.c: 63
+addi_apci_2032.c: 63
+addi_apci_2200.c: 63
+addi_apci_3001.c: 63
+addi_apci_3120.c: 63
+addi_apci_3200.c: 63
+addi_apci_3300.c: 63
+addi_apci_3501.c: 63
+addi_apci_3xxx.c: 63
+addi_apci_all.c: 468
+addi_common.c: 57084
+addi_common.h: 15536
+addi-data: 4096
+addi_eeprom.c: 35657
+addinitrd.c: 3837
+addnote.c: 5117
+addon_cpuid_features.c: 3269
+addRamDisk.c: 9120
+addr.c: 13176
+addrconf.c: 112491
+addrconf_core.c: 2484
+addrconf.h: 7261
+address.c: 10451
+addr.h: 615
+addrlabel.c: 14012
+addr-map.c: 3725
+addr-map.h: 1054
+addrs.h: 14810
+addrspace.h: 4233
+adfs: 4096
+adfs_fs.h: 1337
+adfs.h: 5064
+adfs.txt: 1816
+adi.c: 14310
+adlib.c: 3006
+adl_pci6208.c: 11803
+adl_pci7296.c: 4671
+adl_pci7432.c: 5617
+adl_pci8164.c: 9991
+adl_pci9111.c: 38266
+adl_pci9118.c: 69079
+adm1021: 4184
+adm1021.c: 14057
+adm1025: 2364
+adm1025.c: 19865
+adm1026: 4578
+adm1026.c: 60096
+adm1029.c: 13774
+adm1031: 1193
+adm1031.c: 31209
+adm8211.c: 56115
+adm8211.h: 18093
+adm9240: 6804
+adm9240.c: 24112
+adma.c: 5497
+adma.h: 13803
+adq12b.c: 12147
+ads7828: 1146
+ads7828.c: 8084
+ads7846.c: 31008
+ads7846.h: 1844
+ADSBitsy: 1396
+adssphere.c: 1810
+adt7462: 2515
+adt7462.c: 60645
+adt7470: 2759
+adt7470.c: 42397
+adt7473: 2757
+adt7473.c: 35779
+adt7475: 2578
+adt7475.c: 35318
+adummy.c: 3035
+adutux.c: 25427
+adv7170.c: 9645
+adv7175.c: 10457
+adv7343.c: 12608
+adv7343.h: 730
+adv7343_regs.h: 5764
+advansys: 4096
+advansys.c: 382572
+advansys.txt: 9492
+advantechwdt.c: 8222
+adv_pci1710.c: 46220
+adv_pci1723.c: 12975
+adv_pci_dio.c: 34130
+ae7400074d449189d41fceb6d6f871490d7842: 298
+aead.c: 12873
+aead.h: 2027
+aec62xx.c: 9392
+aedsp16.c: 36369
+ael1002.c: 41054
+aer: 4096
+aerdrv_acpi.c: 1347
+aerdrv.c: 8935
+aerdrv_core.c: 22958
+aerdrv_errprint.c: 5915
+aerdrv.h: 3468
+aer.h: 773
+aer_inject.c: 10715
+aes.c: 11973
+aes_ccm.c: 3589
+aes_ccm.h: 810
+aes_ccmp.c: 14024
+aes_ccmp.h: 1469
+aes_cmac.c: 2737
+aes_cmac.h: 587
+aes_generic.c: 63316
+aes_glue.c: 1691
+aes.h: 279
+aes-i586-asm_32.S: 10637
+aesni-intel_asm.S: 21991
+aesni-intel_glue.c: 19525
+aes_s390.c: 13814
+aes-x86_64-asm_64.S: 4820
+af802154.h: 1271
+af9005.c: 28215
+af9005-fe.c: 36514
+af9005.h: 120579
+af9005-remote.c: 4403
+af9005-script.h: 5193
+af9013.c: 38083
+af9013.h: 3095
+af9013_priv.h: 21508
+af9015.c: 43153
+af9015.h: 28439
+af_ax25.c: 45160
+af_bluetooth.c: 10089
+af_can.c: 23294
+af_can.h: 4053
+af_decnet.c: 54945
+afeb9260_defconfig: 29783
+af_econet.c: 25853
+affs: 4096
+affs.h: 10590
+affs_hardblocks.h: 1481
+affs.txt: 8188
+af_ieee802154.c: 8683
+af_ieee802154.h: 1620
+af_inet6.c: 29847
+af_inet.c: 40041
+af_ipx.c: 50967
+af_irda.c: 67827
+af_irda.h: 2964
+af_iucv.c: 41285
+af_iucv.h: 2495
+af_key.c: 102229
+af_llc.c: 29863
+af_netlink.c: 46590
+af_netrom.c: 33634
+af_packet.c: 55964
+af_phonet.c: 10845
+af_rds.c: 14309
+af_rose.c: 39337
+af_rxrpc.c: 20908
+af_rxrpc.h: 2017
+afs: 4096
+afs.c: 6434
+afs_cm.h: 1213
+afs_fs.h: 2342
+afs.h: 6110
+afs.txt: 7976
+afs_vl.h: 3680
+af_unix.c: 53673
+af_unix.h: 1891
+af_x25.c: 38538
+agent.c: 6214
+agent.h: 2106
+agg-rx.c: 10061
+agg-tx.c: 19983
+agnx: 4096
+agnx.h: 4414
+agp: 4096
+agp_backend.h: 909
+agpgart.h: 6567
+agp.h: 11594
+ah4.c: 7802
+ah6.c: 13438
+aha152x.c: 100462
+aha152x_core.c: 61
+aha152x.h: 10175
+aha152x_stub.c: 7843
+aha152x.txt: 6540
+aha1542.c: 50376
+aha1542.h: 4776
+aha1740.c: 19608
+aha1740.h: 4954
+ahash.c: 5607
+ahb.c: 4740
+ah.c: 3493
+ahci.c: 82058
+ah.h: 894
+aic7770.c: 9851
+aic7770_osm.c: 4437
+aic79xx_core.c: 299904
+aic79xx.h: 46803
+aic79xx_inline.h: 5997
+aic79xx_osm.c: 79947
+aic79xx_osm.h: 21300
+aic79xx_osm_pci.c: 10626
+aic79xx_pci.c: 27694
+aic79xx_pci.h: 3106
+aic79xx_proc.c: 10559
+aic79xx.reg: 73912
+aic79xx_reg.h_shipped: 71718
+aic79xx_reg_print.c_shipped: 19691
+aic79xx.seq: 72735
+aic79xx_seq.h_shipped: 29327
+aic79xx.txt: 24091
+aic7xxx: 4096
+aic7xxx_93cx6.c: 9761
+aic7xxx_93cx6.h: 3670
+aic7xxx_core.c: 216583
+aic7xxx.h: 42160
+aic7xxx_inline.h: 3774
+aic7xxx_old: 4096
+aic7xxx_old.c: 366880
+aic7xxx_old.txt: 24500
+aic7xxx_osm.c: 73118
+aic7xxx_osm.h: 21353
+aic7xxx_osm_pci.c: 12355
+aic7xxx_pci.c: 61842
+aic7xxx_pci.h: 5296
+aic7xxx_proc.c: 10950
+aic7xxx.reg: 38137
+aic7xxx_reg.h: 15305
+aic7xxx_reg.h_shipped: 23099
+aic7xxx_reg_print.c_shipped: 10818
+aic7xxx.seq: 70499
+aic7xxx_seq.c: 20747
+aic7xxx_seq.h_shipped: 32908
+aic7xxx.txt: 19701
+aic94xx: 4096
+aic94xx_dev.c: 11236
+aic94xx_dump.c: 36929
+aic94xx_dump.h: 1451
+aic94xx.h: 3007
+aic94xx_hwi.c: 38875
+aic94xx_hwi.h: 10646
+aic94xx_init.c: 28607
+aic94xx_reg.c: 10895
+aic94xx_reg_def.h: 74147
+aic94xx_reg.h: 10470
+aic94xx_sas.h: 22044
+aic94xx_scb.c: 27220
+aic94xx_sds.c: 37304
+aic94xx_sds.h: 4644
+aic94xx_seq.c: 47415
+aic94xx_seq.h: 2011
+aic94xx_task.c: 17414
+aic94xx_tmf.c: 20129
+aica.c: 18912
+aica.h: 2322
+aicasm: 4096
+aicasm.c: 20235
+aicasm_gram.y: 41937
+aicasm.h: 3213
+aicasm_insformat.h: 5394
+aicasm_macro_gram.y: 4072
+aicasm_macro_scan.l: 4166
+aicasm_scan.l: 15538
+aicasm_symbol.c: 16089
+aicasm_symbol.h: 4889
+aiclib.c: 1599
+aiclib.h: 6327
+aio_abi.h: 3060
+aio_aio12_8.c: 5597
+aio.c: 9345
+aio.h: 530
+aio_iiro_16.c: 4521
+aiptek.c: 63719
+aircable.c: 16905
+airo.c: 224549
+airo_cs.c: 16214
+airo.h: 272
+aironet.c: 38
+aironet.h: 31
+airport.c: 6741
+airq.c: 3567
+airq.h: 530
+ak4104.c: 8783
+ak4104.h: 143
+ak4114.c: 18943
+ak4114.h: 10191
+ak4117.c: 16871
+ak4117.h: 9193
+ak4396.h: 1065
+ak4531_codec.c: 17543
+ak4531_codec.h: 3161
+ak4535.c: 18361
+ak4535.h: 1042
+ak4xxx-adda.c: 25308
+ak4xxx-adda.h: 3333
+ak4xxx.c: 5039
+aki3068net: 4096
+alauda.c: 34485
+alaw_main.csp.ihex: 3714
+alchemy: 4096
+alchemy-flash.c: 4191
+algapi.c: 16668
+algapi.h: 8721
+algboss.c: 6296
+algos: 4096
+ali14xx.c: 6564
+ali5451: 4096
+ali5451.c: 59400
+ali-agp.c: 10369
+alias.c: 1447
+aliasing-test.c: 6103
+aliasing.txt: 8753
+alias.txt: 1181
+align.c: 24429
+alignment.c: 23757
+align.S: 11650
+ali-ircc.c: 57570
+ali-ircc.h: 7748
+alim1535_wdt.c: 10224
+alim15x3.c: 14978
+alim7101_wdt.c: 11048
+allocator.c: 10151
+alloc.c: 10261
+alloc.h: 9219
+allocpercpu.c: 4150
+alpaca.h: 1209
+alpha: 4096
+alpha-agp.c: 5476
+alpha_ksyms.c: 2696
+alphatrack.c: 23326
+alphatrack.h: 2005
+alps.c: 15813
+alps.h: 1047
+ALS: 3770
+als100.c: 9384
+als300.c: 23789
+als4000.c: 32136
+alsa: 4096
+alsa.c: 2430
+ALSA-Configuration.txt: 75006
+alsa-driver-api.tmpl: 3216
+alsa.h: 370
+alternative-asm.h: 289
+alternative.c: 14237
+alternative.h: 5895
+altpciechdma: 4096
+altpciechdma.c: 37598
+am200epd.c: 9652
+am200epdkit_defconfig: 26949
+am300epd.c: 6564
+am79c961a.c: 18502
+am79c961a.h: 3109
+am9513.h: 1940
+amba: 4096
+amba-clcd.c: 12494
+ambakmi.c: 4554
+amba-pl010.c: 19490
+amba-pl011.c: 21509
+amba-pl022.c: 53346
+ambassador.c: 68387
+ambassador.h: 16192
+amcc: 4096
+amcc_s5933_58.h: 14263
+amcc_s5933.h: 6603
+amd5536udc.c: 86854
+amd5536udc.h: 17276
+amd64-agp.c: 20128
+amd64_edac.c: 98492
+amd64_edac_dbg.c: 5401
+amd64_edac_err_types.c: 3628
+amd64_edac.h: 19221
+amd64_edac_inj.c: 4304
+amd74xx.c: 10198
+amd76x_edac.c: 9371
+amd76xrom.c: 9404
+amd7930.c: 31102
+amd7930_fn.c: 23626
+amd7930_fn.h: 1162
+amd8111e.c: 53690
+amd8111_edac.c: 16756
+amd8111_edac.h: 4244
+amd8111e.h: 21006
+amd8131_edac.c: 10985
+amd8131_edac.h: 3772
+amd_bus.c: 13843
+amd.c: 3180
+amd_iommu.c: 52618
+amd_iommu.h: 1421
+amd_iommu_init.c: 34814
+amd_iommu_types.h: 13377
+amd-k7-agp.c: 15673
+amd-powernow.txt: 1673
+amd-rng.c: 3458
+amifb.c: 103212
+amifd.h: 1995
+amifdreg.h: 2674
+amiflop.c: 46962
+amiga: 4096
+amiga.c: 3445
+amiga_defconfig: 28613
+amigaffs.c: 11549
+amigaffs.h: 2927
+amiga.h: 116
+amigahw.h: 11232
+amigaints.h: 3583
+amigaone: 4096
+amigaone_defconfig: 40433
+amigaone.dts: 4189
+amigayle.h: 3135
+amiints.c: 6489
+amijoy.c: 4591
+amijoy.txt: 7701
+amikbd.c: 6468
+amimouse.c: 3296
+amipcmcia.h: 2568
+amiserial.c: 54254
+amisound.c: 2828
+amix86.c: 23331
+amlcode.h: 18976
+aml_nfw.c: 5630
+amlresrc.h: 9975
+amon.h: 141
+amp.c: 2736
+amp.h: 1594
+amplc_dio200.c: 38731
+amplc_pc236.c: 16962
+amplc_pc263.c: 11680
+amplc_pci224.c: 44174
+amplc_pci230.c: 92910
+ams: 4096
+ams-core.c: 6046
+ams-delta.c: 5974
+ams_delta_defconfig: 28481
+amsdu.c: 5428
+ams.h: 1354
+ams-i2c.c: 6365
+ams-input.c: 3542
+amso1100: 4096
+ams-pmu.c: 4469
+analog.c: 20366
+anchor.h: 3882
+anchors.txt: 2625
+android: 4096
+ani.c: 23441
+ani.h: 4062
+anode.c: 14491
+anomaly.h: 11228
+anon_inodes.c: 5477
+anon_inodes.h: 312
+ansi_cprng.c: 10011
+ansidecl.h: 4393
+ans-lcd.c: 3847
+ans-lcd.h: 206
+anubis.c: 28484
+anubis-cpld.h: 652
+anubis-irq.h: 596
+anubis-map.h: 1219
+anycast.c: 11884
+anysee.c: 15434
+anysee.h: 14174
+aoa: 4096
+aoa-gpio.h: 2434
+aoa.h: 3816
+aoe: 4096
+aoeblk.c: 7321
+aoechr.c: 6092
+aoecmd.c: 23023
+aoedev.c: 5392
+aoe.h: 4748
+aoemain.c: 2032
+aoenet.c: 3237
+aoe.txt: 4600
+aops.c: 49318
+aops.h: 4017
+a.out-core.h: 2444
+a.out.h: 2438
+ap325rxa_defconfig: 31462
+apanel.c: 8043
+apb.h: 1043
+ap_bus.c: 45317
+ap_bus.h: 6091
+apc.c: 4412
+apc.h: 1682
+APCI1710_82x54.c: 55614
+APCI1710_82x54.h: 2408
+APCI1710_Chrono.c: 75530
+APCI1710_Chrono.h: 2397
+APCI1710_Dig_io.c: 35243
+APCI1710_Dig_io.h: 1437
+APCI1710_INCCPT.c: 206966
+APCI1710_INCCPT.h: 10615
+APCI1710_Inp_cpt.c: 32511
+APCI1710_Inp_cpt.h: 1414
+APCI1710_Pwm.c: 110859
+APCI1710_Pwm.h: 2722
+APCI1710_Ssi.c: 30348
+APCI1710_Ssi.h: 1343
+APCI1710_Tor.c: 70692
+APCI1710_Tor.h: 1684
+APCI1710_Ttl.c: 35072
+APCI1710_Ttl.h: 1338
+apdbg.c: 12729
+aperture_64.c: 13850
+ap.h: 26
+apic: 4096
+api.c: 4766
+apic.c: 56323
+apicdef.h: 10790
+apic_flat_64.c: 9680
+apic.h: 48
+apicnum.h: 229
+API.html: 738
+api-intro.txt: 6569
+apm_32.c: 71310
+apm-acpi.txt: 1541
+apm_bios.h: 5647
+apm.c: 1961
+apm_emu.c: 3225
+apm-emulation.c: 17959
+apm-emulation.h: 1575
+apm.h: 1722
+apm_power.c: 10334
+apm-power.c: 2659
+apne.c: 17115
+apollo: 4096
+apollo_defconfig: 25574
+apollodma.h: 9409
+apollohw.h: 2876
+appldata: 4096
+appldata_base.c: 16414
+appldata.h: 2269
+appldata_mem.c: 4196
+appldata_net_sum.c: 4240
+appldata_os.c: 6134
+appledisplay.c: 9793
+applesmc.c: 46139
+appletalk: 4096
+appletouch.c: 25051
+appletouch.txt: 3199
+applicom.c: 24465
+applicom.h: 2558
+applying-patches.txt: 19961
+applypatch-msg.sample: 452
+aq100x.c: 8974
+ar7: 4096
+ar7_defconfig: 29419
+ar7.h: 4432
+ar7part.c: 4186
+ar7_wdt.c: 8576
+ar9170: 4096
+ar9170.h: 7335
+ar-accept.c: 12406
+ar-ack.c: 33274
+arbiter.c: 11549
+arbiter.h: 607
+arc: 4096
+arc4.c: 2066
+ar-call.c: 21724
+arc_con.c: 973
+arcdevice.h: 12708
+arcfb.c: 16908
+arcfb.h: 150
+arch: 4096
+arch_checks.c: 3045
+arches_defconfig: 19397
+arches.dts: 7694
+arch.h: 1650
+arch-kev7a400.c: 2933
+arch-lpd7a40x.c: 10208
+archparam.h: 246
+archsetjmp.h: 363
+arch-v10: 4096
+arch-v32: 4096
+arcmsr: 4096
+arcmsr_attr.c: 12953
+arcmsr.h: 22540
+arcmsr_hba.c: 68471
+arcmsr_spec.txt: 22891
+arcnet: 4096
+arcnet.c: 30476
+arcnet-hardware.txt: 112635
+arcnet.txt: 23983
+arcofi.c: 3664
+arcofi.h: 721
+ar-connection.c: 23383
+ar-connevent.c: 9295
+arc-rawmode.c: 5274
+arc-rimi.c: 10949
+ar-error.c: 5949
+argv_split.c: 1893
+ariadne.c: 24224
+ariadne.h: 15566
+ar-input.c: 20380
+ar-internal.h: 28881
+ark3116.c: 12365
+ar-key.c: 8236
+arkfb.c: 31427
+arkfb.txt: 2024
+arlan.h: 16773
+arlan-main.c: 51969
+arlan-proc.c: 30009
+ar-local.c: 7670
+arm: 4096
+armadillo5x0.c: 7149
+ARM-gcc.h: 4503
+armksyms.c: 4758
+arm_timer.h: 576
+ar-output.c: 18343
+arp.c: 35296
+ar-peer.c: 7599
+arp.h: 1028
+ar-proc.c: 5159
+arptable_filter.c: 3496
+arp_tables.c: 47085
+arp_tables.h: 8551
+arpt_mangle.c: 2391
+arpt_mangle.h: 547
+array.c: 13244
+arrayRCU.txt: 4475
+ar-recvmsg.c: 11003
+ar-security.c: 5588
+ar-skbuff.c: 3506
+arthur.c: 2275
+artpec_3_defconfig: 13781
+ar-transport.c: 7196
+arv.c: 22235
+arxescsi.c: 9967
+asb100: 2093
+asb100.c: 29220
+asb2303_defconfig: 13559
+asciidoc.conf: 2238
+asequencer.h: 24733
+ashiftrt.S: 3468
+ashldi3.c: 1516
+__ashldi3.S: 1340
+ashldi3.S: 1594
+ashlsi3.S: 3814
+ashrdi3.c: 1578
+__ashrdi3.S: 1359
+ashrdi3.S: 1594
+ashrsi3.S: 3765
+ashxdi3.S: 5014
+asic3.c: 23429
+asic3.h: 11966
+asids-debugfs.c: 1875
+asi.h: 13855
+asiliantfb.c: 17057
+as-iosched.c: 39676
+as-iosched.txt: 8697
+asix.c: 39119
+as-layout.h: 1666
+asl.c: 9101
+asm: 4096
+asm-compat.h: 1951
+asm-generic: 4096
+asm.h: 9481
+asmmacro-32.h: 4815
+asmmacro-64.h: 3961
+asmmacro.h: 2767
+asm-offsets_32.c: 5194
+asm-offsets_64.c: 3637
+asm-offsets.c: 4611
+asmregs.h: 3115
+asn1.c: 15700
+asoundef.h: 14263
+asound_fm.h: 4313
+asound.h: 39901
+asp8347_defconfig: 35011
+asp834x.c: 2108
+asp834x-redboot.dts: 6941
+asp.c: 3631
+aspenite.c: 2671
+asp.h: 608
+aspm.c: 25790
+Assabet: 9201
+assabet.c: 11283
+assabet_defconfig: 17595
+assabet.h: 4477
+assembler.h: 2834
+assembly.h: 12972
+assoc.c: 36
+assoc.h: 408
+association.h: 4661
+associola.c: 43957
+ast.c: 3630
+ast.h: 878
+asus_acpi.c: 39676
+asus_atk0110.c: 24097
+asuscom.c: 11573
+asus-laptop.c: 36214
+asus_oled: 4096
+asus_oled.c: 18945
+async.c: 11128
+asyncdata.c: 15045
+async.h: 973
+async_memcpy.c: 3227
+async_memset.c: 2994
+async-thread.c: 13350
+async-thread.h: 3400
+async_tx: 4096
+async-tx-api.txt: 8950
+async_tx.c: 8062
+async_tx.h: 5062
+async_xor.c: 9790
+at1700.c: 25461
+at24.c: 17172
+at24.h: 1084
+at25.c: 10286
+at32ap700x.c: 54284
+at32ap700x.h: 9017
+at32ap700x_wdt.c: 10216
+at32psif.c: 8545
+at73c213.c: 28442
+at73c213.h: 3187
+at76c50x-usb.c: 69577
+at76c50x-usb.h: 11556
+at76_usb: 4096
+at76_usb.c: 159931
+at76_usb.h: 18785
+at91_adc.h: 2447
+at91_aic.h: 2578
+at91cap9adk_defconfig: 28118
+at91cap9.c: 9260
+at91cap9_ddrsdr.h: 4803
+at91cap9_devices.c: 32852
+at91cap9.h: 5120
+at91cap9_matrix.h: 8438
+at91_cf.c: 10319
+at91_dbgu.h: 2878
+at91_ether.c: 37656
+at91_ether.h: 3116
+at91_ide.c: 10538
+at91_mci.c: 31894
+at91_mci.h: 5220
+at91_pio.h: 2085
+at91_pit.h: 1189
+at91_pmc.h: 6822
+at91rm9200.c: 8544
+at91rm9200_devices.c: 32118
+at91rm9200dk_defconfig: 19334
+at91rm9200ek_defconfig: 19319
+at91rm9200_emac.h: 6334
+at91rm9200.h: 4634
+at91rm9200_mc.h: 7552
+at91rm9200_time.c: 6137
+at91rm9200_wdt.c: 6655
+at91_rstc.h: 1684
+at91_rtc.h: 3381
+at91_rtt.h: 1335
+at91sam9260.c: 9719
+at91sam9260_devices.c: 28830
+at91sam9260ek_defconfig: 23675
+at91sam9260.h: 5601
+at91sam9260_matrix.h: 4360
+at91sam9261.c: 7811
+at91sam9261_devices.c: 27547
+at91sam9261ek_defconfig: 27131
+at91sam9261.h: 3985
+at91sam9261_matrix.h: 3171
+at91sam9263.c: 8693
+at91sam9263_devices.c: 36564
+at91sam9263ek_defconfig: 27888
+at91sam9263.h: 5088
+at91sam9263_matrix.h: 7531
+at91sam926x_time.c: 4812
+at91sam9g20ek_defconfig: 26082
+at91sam9rl.c: 8144
+at91sam9rl_devices.c: 28643
+at91sam9rlek_defconfig: 21184
+at91sam9rl.h: 4332
+at91sam9rl_matrix.h: 5086
+at91sam9_sdramc.h: 3914
+at91sam9_smc.h: 3570
+at91sam9_wdt.c: 7764
+at91_shdwc.h: 1497
+at91_spi.h: 3738
+at91_ssc.h: 4846
+at91_st.h: 1983
+at91_tc.h: 6897
+at91_twi.h: 3075
+at91_udc.c: 48229
+at91_udc.h: 6283
+at91_wdt.h: 1464
+at91x40.c: 1914
+at91x40.h: 2025
+at91x40_time.c: 2547
+at93c.c: 2613
+at93c.h: 292
+ata: 12288
+ata.c: 4208
+ata_defs_asm.h: 8736
+ata_defs.h: 6434
+atafb.c: 91174
+atafb.h: 1708
+atafb_iplan2p2.c: 6818
+atafb_iplan2p4.c: 7301
+atafb_iplan2p8.c: 8377
+atafb_mfb.c: 2554
+atafb_utils.h: 11235
+atafd.h: 261
+atafdreg.h: 2704
+ataflop.c: 52286
+ata_generic.c: 6543
+atags.c: 1588
+atags.h: 132
+ata.h: 787
+ataints.c: 14727
+atakbd.c: 6402
+atakeyb.c: 15982
+atalk.h: 5240
+atalk_proc.c: 7290
+ata_piix.c: 45848
+ata_platform.h: 910
+atari: 4096
+atari.c: 3911
+atari_defconfig: 26788
+atari.h: 1077
+atarihw.h: 20620
+atariints.h: 5520
+atari_joystick.h: 418
+atarikbd.txt: 26109
+atarikb.h: 1514
+atarilance.c: 34168
+atarimouse.c: 3865
+atari_NCR5380.c: 92608
+atari_scsi.c: 35928
+atari_scsi.h: 5820
+atari_stdma.h: 458
+atari_stram.h: 429
+atasound.c: 2705
+ateb9200_defconfig: 26557
+aten2011.c: 65277
+aten.c: 3343
+ath: 4096
+ath5k: 4096
+ath5k.h: 45994
+ath9k: 4096
+ath9k.h: 20541
+ath9k_platform.h: 1116
+athr_common.h: 4056
+ati-agp.c: 14653
+ati_ids.h: 8172
+atiixp.c: 5592
+atiixp_modem.c: 36739
+ati_pcigart.c: 5516
+ati_remote2.c: 23391
+ati_remote.c: 27913
+atkbd.c: 40410
+atl1c: 4096
+atl1.c: 101403
+atl1c_ethtool.c: 9188
+atl1c.h: 20395
+atl1c_hw.c: 13975
+atl1c_hw.h: 31069
+atl1c_main.c: 77505
+atl1e: 4096
+atl1e_ethtool.c: 11679
+atl1e.h: 17562
+atl1e_hw.c: 16680
+atl1e_hw.h: 38581
+atl1e_main.c: 71172
+atl1e_param.c: 7245
+atl1.h: 24023
+atl2.c: 82456
+atl2.h: 16349
+atlas_btns.c: 4752
+atlx: 4096
+atlx.c: 7198
+atlx.h: 18176
+atm: 4096
+atmapi.h: 889
+atmarp.h: 1233
+atmbr2684.h: 3208
+atmclip.h: 513
+atmdev.h: 16681
+atmel: 4096
+atmel-abdac.h: 626
+atmel-ac97c.h: 1409
+atmel.c: 132756
+atmel_cs.c: 17914
+atmel.h: 1533
+atmel_lcdc.h: 7265
+atmel_lcdfb.c: 31305
+atmel-mci.c: 43139
+atmel-mci.h: 1269
+atmel-mci-regs.h: 6476
+atmel_nand.c: 15137
+atmel_nand_ecc.h: 1412
+atmel_pci.c: 2533
+atmel-pcm.c: 14083
+atmel-pcm.h: 2987
+atmel_pdc.h: 1410
+atmel-pwm-bl.c: 6152
+atmel-pwm-bl.h: 1550
+atmel_pwm.c: 9359
+atmel_pwm.h: 2724
+atmel_read_eeprom.c: 3671
+atmel_read_eeprom.h: 2413
+atmel_serial.c: 40894
+atmel_serial.h: 6087
+atmel_spi.c: 23923
+atmel_spi.h: 4446
+atmel-ssc.c: 3605
+atmel_ssc_dai.c: 20632
+atmel_ssc_dai.h: 3265
+atmel-ssc.h: 9369
+atmel_tc.h: 11075
+atmel_tclib.c: 3626
+atmel_tsadcc.c: 10816
+atmel_usba_udc.c: 50940
+atmel_usba_udc.h: 10031
+atmel-wm97xx.c: 11848
+atm_eni.h: 585
+atm.h: 7995
+atm_he.h: 343
+atm_idt77105.h: 892
+atmioc.h: 1583
+atmlec.h: 2561
+atm_misc.c: 2638
+atmmpc.h: 4163
+atm_nicstar.h: 1215
+atmppp.h: 576
+atmsap.h: 4907
+atmsar11.HEX: 19191
+atm_suni.h: 253
+atmsvc.h: 1790
+atm_sysfs.c: 3945
+atmtcp.c: 11650
+atm_tcp.h: 1768
+atm.txt: 426
+atm_zatm.h: 1606
+atngw100: 4096
+atngw100_defconfig: 28242
+atngw100_evklcd100_defconfig: 29353
+atngw100_evklcd101_defconfig: 29353
+atngw100_mrmt_defconfig: 33751
+atombios_crtc.c: 23254
+atombios.h: 221852
+atom-bits.h: 1882
+atom.c: 29689
+atom.h: 4494
+atomic32.c: 2859
+atomic_32.h: 11086
+atomic_32.S: 2663
+atomic64.c: 3863
+atomic_64.h: 10903
+atomic64.h: 1840
+atomic64-ops.S: 4827
+atomic_64.S: 2925
+atomic-grb.h: 4642
+atomic.h: 7333
+atomic-irq.h: 1375
+atomic-llsc.h: 2813
+atomic-long.h: 5244
+atomic_mm.h: 4061
+atomic_no.h: 3556
+atomic-ops.S: 5339
+atomic_ops.txt: 19503
+atomic-ops.txt: 4632
+atomic.S: 15917
+atom-names.h: 4758
+atom-types.h: 1430
+atp870u.c: 86512
+atp870u.h: 1487
+atp.c: 29816
+atp.h: 8737
+atstk1000: 4096
+atstk1000.h: 535
+atstk1002.c: 8012
+atstk1002_defconfig: 30107
+atstk1003.c: 3765
+atstk1003_defconfig: 25774
+atstk1004.c: 3756
+atstk1004_defconfig: 15379
+atstk1006_defconfig: 32583
+attach.c: 9647
+attr.c: 2666
+attrib.c: 91896
+attrib.h: 4321
+attribute_container.c: 12242
+attribute_container.h: 2530
+atxp1.c: 9417
+aty: 4096
+aty128fb.c: 67277
+aty128fb.txt: 2119
+aty128.h: 13554
+atyfb_base.c: 111634
+atyfb.h: 8973
+au0828: 4096
+au0828-cards.c: 9773
+au0828-cards.h: 1060
+au0828-core.c: 7629
+au0828-dvb.c: 11151
+au0828.h: 7385
+au0828-i2c.c: 9287
+au0828-reg.h: 2134
+au0828-video.c: 41940
+au1000_db1x00.c: 7294
+au1000_dma.h: 11212
+au1000_eth.c: 33708
+au1000_eth.h: 3012
+au1000_generic.c: 14674
+au1000_generic.h: 4280
+au1000.h: 53188
+au1000_ircc.h: 3758
+au1000_pb1x00.c: 9234
+au1000_xxs1500.c: 4378
+au1100fb.c: 20752
+au1100fb.h: 14620
+au1100_mmc.h: 5888
+au1200fb.c: 52491
+au1200fb.h: 18704
+au1550_ac97.c: 51655
+au1550nd.c: 14821
+au1550_spi.c: 26531
+au1550_spi.h: 433
+au1k_ir.c: 20249
+au1x: 4096
+au1x00.c: 19173
+au1xmmc.c: 28453
+au1xxx_dbdma.h: 13134
+au1xxx.h: 1723
+au1xxx-ide.c: 15369
+au1xxx_ide.h: 6491
+AU1xxx_IDE.README: 4039
+au1xxx_psc.h: 15895
+au6610.c: 6091
+au6610.h: 1286
+au8522_decoder.c: 27416
+au8522_dig.c: 21506
+au8522.h: 2387
+au8522_priv.h: 17128
+au8810.c: 379
+au8810.h: 7007
+au8820.c: 331
+au8820.h: 6479
+au8830.c: 404
+au8830.h: 8629
+au88x0: 4096
+au88x0_a3d.c: 25257
+au88x0_a3ddata.c: 2908
+au88x0_a3d.h: 4336
+au88x0.c: 10316
+au88x0_core.c: 78891
+au88x0_eq.c: 23045
+au88x0_eqdata.c: 3952
+au88x0_eq.h: 1287
+au88x0_game.c: 3655
+au88x0.h: 8929
+au88x0_mixer.c: 773
+au88x0_mpu401.c: 3619
+au88x0_pcm.c: 15858
+au88x0_synth.c: 11076
+au88x0_wt.h: 2347
+au88x0_xtalk.c: 23426
+au88x0_xtalk.h: 2304
+Audigy-mixer.txt: 13956
+audio.c: 7519
+AudioExcelDSP16: 3886
+audio.h: 525
+Audiophile-Usb.txt: 17915
+audit_64.c: 1870
+audit.c: 1888
+audit_change_attr.h: 320
+audit_dir_write.h: 238
+auditfilter.c: 34110
+audit.h: 394
+audit_read.h: 127
+auditsc.c: 67706
+audit_signal.h: 36
+audit_tree.c: 22256
+audit_watch.c: 14765
+audit_write.h: 255
+aureon.c: 64017
+aureon.h: 2419
+autcpu12.c: 5831
+autcpu12.h: 2590
+autcpu12-nvram.c: 3124
+auth.c: 35
+authenc.c: 13429
+authenc.h: 609
+auth_generic.c: 4800
+auth_gss: 4096
+auth_gss.c: 40950
+auth_gss.h: 2256
+auth.h: 540
+auth_null.c: 2607
+authorization.txt: 2640
+authors: 38
+AUTHORS: 38
+auth_rsp.c: 39
+auth_unix.c: 5607
+auto_dev-ioctl.h: 5186
+autofs: 4096
+autofs4: 4096
+auto_fs4.h: 4095
+autofs4-mount-control.txt: 17706
+auto_fs.h: 2467
+autofs_i.h: 7355
+autoload.c: 967
+autoload.sh: 339
+automount-support.txt: 4694
+autoprobe.c: 4772
+auxdisplay: 4096
+auxio_32.c: 3721
+auxio_32.h: 2622
+auxio_64.c: 3214
+auxio_64.h: 3266
+auxio.h: 176
+aux_reg.h: 646
+auxvec.h: 60
+av7110: 4096
+av7110_av.c: 40033
+av7110_av.h: 1214
+av7110.c: 82729
+av7110_ca.c: 9180
+av7110_ca.h: 441
+av7110.h: 7155
+av7110_hw.c: 31995
+av7110_hw.h: 12512
+av7110_ipack.c: 7991
+av7110_ipack.h: 402
+av7110_ir.c: 11196
+av7110_v4l.c: 27884
+avc.c: 24534
+avc.h: 3102
+avc_ss.h: 617
+avermedia.txt: 13922
+avila.h: 917
+avila-pci.c: 1817
+avila-setup.c: 4610
+av_inherit.h: 1693
+avm: 4096
+avm_a1.c: 8303
+avma1_cs.c: 9468
+avm_a1p.c: 7146
+avmcard.h: 13933
+avm_cs.c: 9107
+avm_pci.c: 23187
+av_permissions.h: 53693
+av_perm_to_string.h: 10893
+avr32: 4096
+__avr32_asr64.S: 560
+avr32_ksyms.c: 1843
+__avr32_lsl64.S: 559
+__avr32_lsr64.S: 559
+avtab.c: 12842
+avtab.h: 2874
+aw2: 4096
+aw2-alsa.c: 22536
+aw2-saa7146.c: 12816
+aw2-saa7146.h: 3650
+aw2-tsl.c: 4092
+awacs.c: 32895
+awacs.h: 8192
+ax25: 4096
+ax25_addr.c: 6217
+ax25_dev.c: 4867
+ax25_ds_in.c: 7261
+ax25_ds_subr.c: 5218
+ax25_ds_timer.c: 5960
+ax25.h: 2752
+ax25_iface.c: 5067
+ax25_in.c: 10789
+ax25_ip.c: 5405
+ax25_out.c: 8933
+ax25_route.c: 11432
+ax25_std_in.c: 11343
+ax25_std_subr.c: 2329
+ax25_std_timer.c: 4335
+ax25_subr.c: 7113
+ax25_timer.c: 5261
+ax25.txt: 610
+ax25_uid.c: 5032
+ax88796.c: 25354
+ax88796.h: 751
+axisflashmap.c: 11854
+axisflashmap.h: 1932
+axnet_cs.c: 55656
+axon_msi.c: 11768
+axonram.c: 9510
+azt2320.c: 9995
+azt3328.c: 74771
+azt3328.h: 16466
+b128ops.h: 2471
+b180_defconfig: 30806
+b1.c: 20917
+b1dma.c: 24682
+b1isa.c: 6013
+b1lli.h: 1654
+b1pci.c: 10903
+b1pcmcia.c: 5718
+b1pcmcia.h: 666
+b2: 4096
+b2c2: 4096
+b3dfg: 4096
+b3dfg.c: 29136
+b43: 4096
+b43.h: 34564
+b43legacy: 4096
+b43legacy.h: 26792
+b43_pci_bridge.c: 1563
+b44.c: 58926
+b44.h: 17577
+ba_action.c: 43
+baboon.c: 2869
+backchannel_rqst.c: 9002
+backend-api.txt: 23417
+backend.c: 8969
+background.c: 4246
+backing-dev.c: 7753
+backing-dev.h: 7625
+backing_ops.c: 11152
+backlight: 4096
+backlight.c: 8488
+backlight.h: 1076
+backoff.h: 514
+backtrace.c: 2048
+backtrace.S: 3769
+backtracetest.c: 2135
+badge4.c: 7278
+badge4_defconfig: 25237
+badge4.h: 2530
+bad_inode.c: 8103
+bad_memory.txt: 1113
+balance: 5103
+balloc.c: 28466
+balloon.c: 15823
+bamboo.c: 1219
+bamboo_defconfig: 23088
+bamboo.dts: 7833
+barrier.h: 751
+barrier.txt: 10841
+base: 4096
+baseband.c: 69836
+baseband.h: 5142
+base.c: 17017
+base.h: 5692
+base.S: 2976
+bas-gigaset.c: 70245
+basic: 4096
+basic-pm-debugging.txt: 10323
+basic_profiling.txt: 1707
+basler: 4096
+bast-cpld.h: 1556
+bast-ide.c: 2522
+bast-irq.c: 3575
+bast-irq.h: 842
+bast-map.h: 5001
+bast-pmu.h: 1140
+battery.c: 26147
+baycom_epp.c: 34930
+baycom.h: 820
+baycom_par.c: 16899
+baycom_ser_fdx.c: 21220
+baycom_ser_hdx.c: 21005
+baycom.txt: 7038
+bbc_envctrl.c: 15825
+bbc.h: 9957
+bbc_i2c.c: 9865
+bbc_i2c.h: 1987
+bbm.h: 4408
+bcache.h: 1450
+bcast.c: 21337
+bcast.h: 5594
+bcd.c: 257
+bcd.h: 195
+bcm1480: 4096
+bcm1480_int.h: 18356
+bcm1480_l2c.h: 8696
+bcm1480_mc.h: 51843
+bcm1480_regs.h: 42338
+bcm1480_scd.h: 15457
+bcm203x.c: 7066
+bcm3510.c: 21894
+bcm3510.h: 1667
+bcm3510_priv.h: 9194
+bcm47xx: 4096
+bcm47xx_defconfig: 44162
+bcm47xx.h: 914
+bcm47xx_wdt.c: 6278
+bcm5974.c: 22743
+bcm5974.txt: 2275
+bcm.c: 39855
+bcm.h: 2057
+bcom_ata_task.c: 1873
+bcom_fec_rx_task.c: 2688
+bcom_fec_tx_task.c: 3548
+bcom_gen_bd_rx_task.c: 1901
+bcom_gen_bd_tx_task.c: 2118
+bc_svc.c: 2387
+bcu.c: 5507
+bc_xprt.h: 1873
+bdx.bin.ihex: 117765
+beacon.c: 16577
+bearer.c: 17977
+bearer.h: 6277
+beat.c: 5680
+beat.h: 1477
+beat_htab.c: 12023
+beat_hvCall.S: 4654
+beat_interrupt.c: 7398
+beat_interrupt.h: 1147
+beat_iommu.c: 3142
+beat_smp.c: 2934
+beat_spu_priv1.c: 5295
+beat_syscall.h: 9338
+beat_udbg.c: 2419
+beat_wrapper.h: 7284
+be_byteshift.h: 1424
+be_cmds.c: 28134
+be_cmds.h: 21092
+beep.c: 7937
+be_ethtool.c: 10213
+befs: 4096
+befs_fs_types.h: 5040
+befs.h: 3265
+befs.txt: 3636
+be.h: 9794
+be_hw.h: 6736
+belkin_sa.c: 17581
+belkin_sa.h: 5114
+be_main.c: 53536
+be_memmove.h: 770
+Benchmark.h: 14912
+benet: 4096
+berry_charge.c: 5094
+bestcomm: 4096
+bestcomm.c: 13444
+bestcomm.h: 5696
+bestcomm_priv.h: 10178
+be_struct.h: 749
+BF518F-EZBRD_defconfig: 30487
+bf518.h: 3233
+BF526-EZBRD_defconfig: 37925
+BF527-EZKIT_defconfig: 39344
+bf527.h: 3368
+BF533-EZKIT_defconfig: 27699
+bf533.h: 3987
+BF533-STAMP_defconfig: 31991
+bf537.h: 3679
+BF537-STAMP_defconfig: 33322
+BF538-EZKIT_defconfig: 31824
+bf538.h: 3110
+BF548-EZKIT_defconfig: 41918
+bf548.h: 3408
+bf54x-keys.c: 10383
+bf54x_keys.h: 373
+bf54x-lq043fb.c: 19521
+bf54x-lq043.h: 486
+BF561-EZKIT_defconfig: 27483
+bf561.h: 5899
+bf5xx-ac97.c: 10719
+bf5xx-ac97.h: 1698
+bf5xx-ac97-pcm.c: 13449
+bf5xx-ac97-pcm.h: 595
+bf5xx-ad1980.c: 3043
+bf5xx-ad73311.c: 6491
+bf5xx-i2s.c: 8397
+bf5xx-i2s.h: 321
+bf5xx-i2s-pcm.c: 7810
+bf5xx-i2s-pcm.h: 591
+bf5xx_nand.c: 19911
+bf5xx-sport.c: 26015
+bf5xx-sport.h: 5191
+bf5xx-ssm2602.c: 4846
+bfin_5xx.c: 37574
+bfin5xx_spi.h: 3282
+bfin-async-flash.c: 5961
+bfin_cf_pcmcia.c: 8045
+bfind.c: 4484
+bfin_dma_5xx.c: 13838
+bfin-global.h: 3579
+bfin_gpio.c: 31670
+bfin-gpio-notes.txt: 2459
+bfin_jtag_comm.c: 9699
+bfin_ksyms.c: 3302
+bfin_mac.c: 29136
+bfin_mac.h: 1654
+bfin_oprofile.c: 303
+bfin-otp.c: 4874
+bfin_sdh.h: 273
+bfin_serial_5xx.h: 5124
+bfin_simple_timer.h: 446
+bfin_sir.c: 18943
+bfin_sir.h: 5300
+bfin_sport.h: 3839
+bfin_sport_uart.c: 16463
+bfin_sport_uart.h: 3726
+bfin-t350mcqb-fb.c: 16570
+bfin_wdt.c: 11813
+bfrom.h: 3443
+bfs: 4096
+bfs_fs.h: 1830
+bfs.h: 1424
+bfs.txt: 2118
+bfusb.c: 17036
+bif_core_defs_asm.h: 15240
+bif_core_defs.h: 9672
+bif_dma_defs_asm.h: 22539
+bif_dma_defs.h: 14998
+bif_slave_defs_asm.h: 11664
+bif_slave_defs.h: 8256
+big_endian.h: 3729
+big-endian.S: 304
+BIG.FAT.WARNING: 234
+bigsmp_32.c: 6414
+bigsur_defconfig: 32018
+bigsur.h: 1540
+bin2c.c: 702
+bin2hex.c: 755
+bin.c: 11164
+bind_addr.c: 13678
+bind.c: 7327
+bindec.S: 28113
+binder.c: 105864
+binder.h: 9073
+bind.h: 1305
+binding.txt: 3687
+binfmt_aout.c: 13156
+binfmt_elf32.c: 3565
+binfmt_elf.c: 55465
+binfmt_elf_fdpic.c: 48887
+binfmt_elfn32.c: 3368
+binfmt_elfo32.c: 4508
+binfmt_em86.c: 2848
+binfmt_flat.c: 27410
+binfmt_loader.c: 1116
+binfmt_misc.c: 15436
+binfmt_misc.txt: 6108
+binfmt_script.c: 2829
+binfmts.h: 4146
+binfmt_som.c: 7567
+binoffset.c: 4039
+binstr.S: 4302
+bio.c: 39950
+biodoc.txt: 55452
+bio.h: 20583
+bio-integrity.c: 21385
+bios32.c: 17673
+bios.c: 2953
+bioscall.S: 1566
+bioscalls.c: 13235
+bios_ebda.h: 794
+bios.h: 3282
+bios_uv.c: 4629
+bitblit.c: 10909
+bitext.c: 2979
+bitext.h: 613
+bitfield.h: 19835
+bitmap.c: 45202
+bitmap.h: 10515
+bit_operations.h: 5627
+bitops: 4096
+bitops_32.h: 2988
+bitops_64.h: 2428
+bitops.c: 1091
+bitops-grb.h: 6325
+bitops.h: 3153
+bitops-llsc.h: 2819
+bitops_mm.h: 11048
+bitops_no.h: 8097
+bitops-op32.h: 3832
+bitops.S: 2667
+bitrev.c: 2157
+bitrev.h: 270
+bits.h: 2634
+bitsperlong.h: 37
+bit_spinlock.h: 2210
+bitstream.bin.ihex: 33395
+bitstream.HEX: 192281
+bkm_a4t.c: 9149
+bkm_a8.c: 11765
+bkm_ax.h: 4575
+blackfin: 4096
+blackfin.c: 7552
+blackfin.h: 1089
+blackfin_sram.h: 1207
+blacklist.c: 8658
+blacklist.h: 108
+blackstamp.c: 9838
+BlackStamp_defconfig: 27434
+blinken.h: 617
+blizzard.c: 41338
+blizzard.h: 249
+blk-barrier.c: 9923
+blkcipher.c: 19013
+blk-core.c: 65533
+blkdev.h: 38233
+blk-exec.c: 2683
+blk.h: 4565
+blkif.h: 3398
+blk-integrity.c: 10137
+blk-ioc.c: 4083
+blk-map.c: 8314
+blk-merge.c: 9996
+blkpg.h: 1569
+blk-settings.c: 21842
+blk-softirq.c: 4192
+blk-sysfs.c: 12022
+blk-tag.c: 10090
+blk-timeout.c: 5850
+blktrace_api.h: 7347
+blktrace.c: 40749
+blktrans.h: 1935
+bloat-o-meter: 1711
+block: 4096
+block2mtd.c: 10757
+block.c: 15974
+blockcheck.c: 16817
+blockcheck.h: 3928
+blockdev: 4096
+block_dev.c: 37737
+blockgroup_lock.h: 1164
+block.h: 12870
+blockops.S: 2573
+block_validity.c: 6187
+blowfish.c: 17890
+bluecard_cs.c: 21854
+bluetooth: 4096
+bluetooth.h: 4823
+bmac.c: 42545
+bmac.h: 8220
+bmap.c: 17082
+bmap.h: 8896
+bmap_union.h: 1274
+bnep: 4096
+bnep.h: 4313
+bnode.c: 15448
+bnx2: 4096
+bnx2.c: 204472
+bnx2_fw.h: 2909
+bnx2.h: 328128
+bnx2i: 4096
+bnx2i.h: 23900
+bnx2i_hwi.c: 73780
+bnx2i_init.c: 11868
+bnx2i_iscsi.c: 56395
+bnx2i_sysfs.c: 3632
+bnx2-mips-06-4.6.16.fw.ihex: 255140
+bnx2-mips-09-4.6.17.fw.ihex: 255536
+bnx2-rv2p-06-4.6.16.fw.ihex: 19256
+bnx2-rv2p-09-4.6.15.fw.ihex: 21444
+bnx2x_dump.h: 28960
+bnx2x-e1-4.8.53.0.fw.ihex: 455912
+bnx2x-e1h-4.8.53.0.fw.ihex: 529144
+bnx2x_fw_defs.h: 15968
+bnx2x_fw_file_hdr.h: 1226
+bnx2x.h: 36495
+bnx2x_hsi.h: 87970
+bnx2x_init.h: 12172
+bnx2x_init_ops.h: 12435
+bnx2x_link.c: 162411
+bnx2x_link.h: 6119
+bnx2x_main.c: 321334
+bnx2x_reg.h: 308654
+board-1arm.c: 2699
+board-2430sdp.c: 5365
+board-3430sdp.c: 12788
+board-4430sdp.c: 2343
+board-a9m9750dev.c: 3624
+board-a9m9750dev.h: 478
+board-acs5k.c: 5495
+board-afeb-9260v1.c: 5234
+board-ams-delta.c: 6109
+board-ams-delta.h: 3023
+board-ap325rxa.c: 13583
+board-apollon.c: 8566
+board-armadillo5x0.h: 564
+board.c: 3934
+board-cam60.c: 4681
+board-cap9adk.c: 9718
+board-carmeva.c: 4435
+board-csb337.c: 6265
+board-csb637.c: 3642
+board-dk.c: 5862
+board-dm355-evm.c: 7541
+board-dm355-leopard.c: 7584
+board-dm644x-evm.c: 17303
+board-dm646x-evm.c: 5912
+board-dsm320.c: 2919
+board-eb01.c: 1385
+board-eb9200.c: 3461
+board-eb.h: 3843
+board-ecbat91.c: 4404
+board-edosk7760.c: 4611
+board-ek.c: 5054
+boardergo.c: 16200
+boardergo.h: 4069
+board-espt.c: 2426
+board-fsample.c: 8474
+board-generic.c: 1918
+board.h: 3611
+board-h2.c: 10497
+board-h2.h: 1585
+board-h2-mmc.c: 1862
+board-h3.c: 9698
+board-h3.h: 1550
+board-h3-mmc.c: 1668
+board-h4.c: 9524
+board-halibut.c: 2112
+board-innovator.c: 10872
+board-jscc9p9360.c: 457
+board-jscc9p9360.h: 390
+board-kafa.c: 2778
+board-kb9202.c: 3738
+board-ldp.c: 9161
+board-magicpanelr2.c: 11382
+board-micrel.c: 1450
+board-mx21ads.h: 1998
+board-mx27ads.h: 10858
+board-mx27lite.h: 544
+board-mx27pdk.h: 541
+board-mx31ads.h: 3850
+board-mx31lilly.h: 1430
+board-mx31lite.h: 508
+board-mx31moboard.h: 1408
+board-mx31pdk.h: 2120
+board-mx35pdk.h: 1062
+board-neocore926.c: 9196
+board-nokia770.c: 9780
+board-omap3beagle.c: 10647
+board-omap3evm.c: 7649
+board-omap3pandora.c: 10350
+board-osk.c: 15556
+board-overo.c: 11768
+board-palmte.c: 9495
+board-palmtt.c: 7148
+board-palmz71.c: 8139
+board-pb1176.h: 3534
+board-pb11mp.h: 3933
+board-pba8.h: 3279
+board-pbx.h: 4735
+board-pcm037.h: 1039
+board-pcm038.h: 1428
+board-pcm043.h: 1039
+board-perseus2.c: 7106
+board-picotux200.c: 4544
+board-polaris.c: 3273
+board-qil-a9260.c: 6417
+board-qong.h: 590
+board-rut1xx.c: 2111
+board-rx51.c: 2237
+board-rx51-peripherals.c: 9630
+boards: 4096
+board-sam9260ek.c: 8166
+board-sam9261ek.c: 14425
+board-sam9263ek.c: 10154
+board-sam9g20ek.c: 7036
+board-sam9-l9260.c: 5065
+board-sam9rlek.c: 5294
+boards.c: 9634
+board-se7619.c: 368
+board_setup.c: 991
+board-sffsdr.c: 5298
+boards.h: 874
+board-sh7785lcr.c: 8051
+board-shmin.c: 715
+board-sx1.c: 10319
+board-sx1.h: 1472
+board-sx1-mmc.c: 1614
+board.txt: 1400
+board-urquell.c: 4834
+board-usb-a9260.c: 5382
+board-usb-a9263.c: 5692
+board-voiceblue.c: 6718
+board-voiceblue.h: 552
+board-yl-9200.c: 19259
+board-zoom2.c: 2568
+board-zoom-debugboard.c: 3833
+bond_3ad.c: 81880
+bond_3ad.h: 9440
+bond_alb.c: 45790
+bond_alb.h: 4802
+bonding: 4096
+bonding.h: 10602
+bonding.txt: 98243
+bond_ipv6.c: 5432
+bond_main.c: 137243
+bond_sysfs.c: 42050
+bonito64.h: 16247
+bonito-irq.c: 2465
+booke.c: 16034
+booke_emulate.c: 6991
+booke.h: 2429
+booke_interrupts.S: 11644
+booke_wdt.c: 4745
+boot: 4096
+boot2.H16: 14566
+boot.c: 8143
+bootcode.bin.ihex: 604
+boot-elf: 4096
+bootflag.c: 1698
+bootgraph.pl: 5753
+boot.h: 1195
+boot.H16: 14980
+boot_head.S: 4023
+bootinfo.h: 3250
+Booting: 4704
+booting.txt: 5755
+booting-without-of.txt: 61721
+boot.ld: 812
+boot.lds.S: 927
+bootloader.c: 3823
+bootloader.lds: 501
+bootlogo.h: 236895
+bootlogo.pl: 165
+bootmem.c: 19242
+bootmem.h: 4841
+boot-options.txt: 12803
+bootp: 4096
+bootparam.h: 1530
+bootp.c: 5689
+bootp.lds: 695
+bootpz.c: 13415
+boot-redboot: 4096
+Boot.S: 2820
+bootstd.h: 4709
+bootstr_32.c: 1207
+bootstr_64.c: 1055
+bootstrap.asm: 2924
+bootstrap.bin.ihex: 1080
+bootstrap.S: 4829
+boot.txt: 35058
+bootwrapper.txt: 7768
+bootx.h: 5211
+bootx_init.c: 16762
+bottom_half.h: 224
+bounce.c: 6616
+bounds.c: 526
+bpa10x.c: 10967
+bpck6.c: 6457
+bpck.c: 9505
+bpqether.c: 14923
+bpqether.h: 952
+bq24022.c: 4006
+bq24022.h: 728
+bq27x00_battery.c: 8343
+br2684.c: 20774
+braille: 4096
+braille_console.c: 8194
+braille-console.txt: 1458
+branch.c: 5609
+branches: 4096
+branch.h: 794
+br.c: 2297
+brcmphy.h: 277
+brd.c: 13994
+br_device.c: 4305
+break.h: 1512
+break.S: 20777
+brec.c: 13153
+br_fdb.c: 10129
+br_forward.c: 3296
+brg.txt: 450
+bridge: 4096
+bridge.h: 29862
+bridge-regs.h: 1121
+bridge.txt: 382
+br_if.c: 9454
+br_input.c: 4146
+br_ioctl.c: 9353
+briq_panel.c: 5383
+brl_emu.c: 5592
+br_netfilter.c: 28764
+br_netlink.c: 4931
+br_notify.c: 2202
+broadcom.c: 17870
+broadsheetfb.c: 13698
+broadsheetfb.h: 1727
+br_private.h: 7906
+br_private_stp.h: 1654
+br_stp_bpdu.c: 5251
+br_stp.c: 11134
+br_stp_if.c: 7340
+br_stp_timer.c: 4651
+br_sysfs_br.c: 12447
+br_sysfs_if.c: 6540
+Brutus: 1927
+bsbe1.h: 3346
+bsd_comp.c: 29587
+bsg.c: 23964
+bsg.h: 3096
+bsr.c: 8971
+bsru6.h: 3855
+bssdb.c: 59681
+bssdb.h: 9978
+bt3c_cs.c: 16786
+bt431.h: 5854
+bt455.h: 2096
+bt819.c: 14549
+bt819.h: 1082
+bt848.h: 11788
+bt856.c: 7085
+bt866.c: 6222
+bt878.c: 16114
+bt878.h: 4113
+bt87x.c: 30530
+Bt87x.txt: 2597
+bt8xx: 4096
+bt8xxgpio.c: 8476
+bt8xxgpio.txt: 4402
+bt8xx.txt: 3940
+btaudio: 3104
+btcx-risc.c: 6470
+btcx-risc.h: 863
+bte.c: 12913
+bte_error.c: 7665
+bte.h: 7765
+btext.c: 38463
+btext.h: 858
+btfixup.c: 10268
+btfixup.h: 7304
+btfixupprep.c: 11589
+btnode.c: 8474
+btnode.h: 2067
+btree.c: 8032
+btree.h: 5488
+btrfs: 4096
+btrfs_inode.h: 4339
+btrfs.txt: 2918
+btsdio.c: 8446
+bttv: 4096
+bttv-audio-hook.c: 9617
+bttv-audio-hook.h: 1126
+bttv-cards.c: 151213
+bttv-driver.c: 121604
+bttv-gpio.c: 4858
+bttv.h: 14877
+bttv-i2c.c: 10677
+bttv-if.c: 2894
+bttv-input.c: 10597
+bttvp.h: 14108
+bttv-risc.c: 25965
+bttv-vbi.c: 12835
+btuart_cs.c: 15857
+btusb.c: 24625
+buddha.c: 5673
+budget-av.c: 45832
+budget.c: 23026
+budget-ci.c: 46442
+budget-core.c: 17319
+budget.h: 3030
+budget-patch.c: 20598
+buffer.c: 3308
+buffer-format.txt: 4606
+buffer_head.h: 11463
+buffer_head_io.c: 10961
+buffer_head_io.h: 2416
+buffer_icap.c: 10726
+buffer_icap.h: 2297
+buffer_sync.c: 13744
+buffer_sync.h: 432
+bug.c: 423
+bugfix.S: 14062
+bug.h: 400
+BUG-HUNTING: 8326
+BUGS: 235
+bugs_64.c: 778
+bugs.c: 1893
+bugs.h: 451
+BUGS-parport: 319
+build.c: 39439
+builddeb: 5872
+buildtar: 2659
+builtin-annotate.c: 29512
+builtin.h: 1035
+builtin-help.c: 11520
+builtin-list.c: 408
+builtin-record.c: 14786
+builtin-report.c: 35243
+builtin-stat.c: 13788
+builtin-top.c: 17061
+bunzip2.h: 258
+burgundy.c: 25045
+burgundy.h: 4105
+bus.c: 8958
+busctl-regs.h: 2071
+bus.h: 950
+BusLogic.c: 151498
+BusLogic.h: 40976
+BusLogic.txt: 26440
+bus-osm.c: 4125
+busses: 4096
+bust_spinlocks.c: 636
+bus.txt: 4536
+bus_watcher.c: 7864
+butterfly: 2990
+button.c: 12060
+buttons.c: 1516
+bvme6000: 4096
+bvme6000_defconfig: 24611
+bvme6000hw.h: 3490
+bvme6000_scsi.c: 3343
+bw2.c: 9440
+bw-qcam.c: 25715
+bw-qcam.h: 2049
+byteorder: 4096
+byteorder.h: 277
+bzero.S: 3581
+c101.c: 11218
+c16e9e8bb74f14f4504305957e4346e7fc46ea: 296
+c2_ae.c: 9166
+c2_ae.h: 3338
+c2_alloc.c: 4106
+c2.c: 33727
+c2_cm.c: 9984
+c2_cq.c: 10526
+c2.h: 13957
+c2_intr.c: 5630
+c2k.c: 3705
+c2k_defconfig: 48649
+c2k.dts: 8777
+c2_mm.c: 8862
+c2_mq.c: 4622
+c2_mq.h: 3238
+c2p_core.h: 2688
+c2_pd.c: 3012
+c2p.h: 631
+c2p_iplan2.c: 3576
+c2port: 4096
+c2port-duramar2150.c: 3241
+c2port.h: 1788
+c2port.txt: 2848
+c2p_planar.c: 3697
+c2_provider.c: 21747
+c2_provider.h: 4101
+c2_qp.c: 25022
+c2_rnic.c: 16782
+c2_status.h: 5103
+c2_user.h: 2415
+c2_vq.c: 7741
+c2_vq.h: 2530
+c2_wr.h: 35475
+c3000_defconfig: 37418
+c4.c: 33871
+c67x00: 4096
+c67x00-drv.c: 6069
+c67x00.h: 9392
+c67x00-hcd.c: 10012
+c67x00-hcd.h: 4298
+c67x00-ll-hpi.c: 12221
+c67x00-sched.c: 30459
+c6xdigio.c: 13668
+ca0106: 4096
+ca0106.h: 37992
+ca0106_main.c: 59396
+ca0106_mixer.c: 27767
+ca0106_proc.c: 14457
+cacheasm.h: 3274
+cache.c: 10301
+cache-c.c: 733
+cachectl.h: 752
+cache-debugfs.c: 3861
+cache-fa.S: 5726
+cachefeatures.txt: 1538
+cache-feroceon-l2.c: 8394
+cache-feroceon-l2.h: 358
+cachefiles: 4096
+cachefiles.txt: 17132
+cacheflush_32.h: 3544
+cacheflush_64.h: 2543
+cacheflush.h: 7154
+cacheflush_mm.h: 4194
+cache-flush-mn10300.S: 5528
+cacheflush_no.h: 2672
+cacheflush.S: 1897
+cache.h: 4660
+cacheinfo.c: 20221
+cacheinfo.h: 240
+cacheinit.c: 1960
+cache-l2x0.c: 3064
+cache-l2x0.h: 1931
+cache-lock.txt: 1222
+cache-mn10300.S: 6477
+cacheops.h: 2183
+cache-page.c: 1964
+cache.S: 2858
+cache-sh2a.c: 3241
+cache-sh2.c: 2044
+cache-sh3.c: 2486
+cache-sh4.c: 20825
+cache-sh5.c: 27270
+cache-sh7705.c: 5050
+cachetlb.txt: 16265
+cachetype.h: 1643
+cache-v3.S: 3174
+cache-v4.S: 3364
+cache-v4wb.S: 5731
+cache-v4wt.S: 4411
+cache-v6.S: 6450
+cache-v7.S: 7015
+cache-xsc3l2.c: 5806
+caching: 4096
+cafe_ccic: 2424
+cafe_ccic.c: 53700
+cafe_ccic-regs.h: 6845
+cafe_nand.c: 25500
+cagg.c: 110445
+cagg.h: 15067
+ca.h: 3022
+caiaq: 4096
+caleb.c: 3138
+caleb.h: 636
+calgary.h: 2452
+calib.c: 28905
+calib.h: 3835
+calibrate.c: 5121
+callback.c: 9965
+callback.h: 2994
+callback_proc.c: 6012
+callbacks.c: 7878
+callbacks.h: 1495
+callback_srm.S: 2840
+callbacks.txt: 4860
+callback_xdr.c: 18050
+callc.c: 48919
+callchain.c: 3746
+callchain.h: 711
+call_hpt.h: 3078
+calling.h: 5596
+call_o32.S: 2534
+call_pci.h: 7934
+call_sm.h: 1270
+calls.S: 10619
+cam60_defconfig: 28038
+camellia.c: 35950
+camera.h: 1504
+cam.h: 4590
+ca_midi.c: 8689
+ca_midi.h: 2024
+can: 4096
+can.h: 3326
+can.txt: 35254
+canyonlands_defconfig: 25711
+canyonlands.dts: 14369
+capability.c: 8203
+capability.h: 17864
+capability.txt: 618
+capcella_defconfig: 18424
+capcella.h: 1486
+capi: 4096
+capi20.h: 29357
+capi.c: 33038
+capicmd.h: 4663
+capidrv.c: 64650
+capidrv.h: 4862
+capidtmf.c: 26932
+capidtmf.h: 3726
+capifs.c: 5266
+capifs.h: 360
+capifunc.c: 31377
+capifunc.h: 903
+capi.h: 10360
+capilib.c: 4606
+capilli.h: 3567
+capimain.c: 3336
+capiutil.c: 30023
+capiutil.h: 14649
+capmode.c: 8041
+caps.c: 5160
+capture.c: 9562
+capture.h: 702
+card: 4096
+cardbus.c: 6323
+card.c: 10228
+card.h: 4366
+CARDLIST.au0828: 527
+CARDLIST.bttv: 9061
+CARDLIST.cx23885: 1693
+CARDLIST.cx88: 5876
+CARDLIST.em28xx: 4880
+CARDLIST.ivtv: 1163
+CARDLIST.saa7134: 9829
+CARDLIST.tuner: 2995
+CARDLIST.usbvision: 4940
+Cards: 26708
+cards.txt: 4752
+cardtype.h: 39894
+carmel.h: 1969
+carmeva_defconfig: 13180
+carminefb.c: 22690
+carminefb.h: 2251
+carminefb_regs.h: 6940
+carta_random.S: 1032
+casio-e55: 4096
+cassini.bin.ihex: 6246
+cassini.c: 145494
+cassini.h: 125724
+cast5.c: 34939
+cast6.c: 22021
+catalog.c: 10749
+catas.c: 4281
+catc.c: 24085
+cats-hw.c: 2052
+cats-pci.c: 1313
+cavium-octeon: 4096
+cavium-octeon_defconfig: 22786
+cayman_defconfig: 31979
+cb710: 4096
+cb710.h: 6584
+cb710-mmc.c: 22406
+cb710-mmc.h: 3337
+cbaf.c: 20405
+cbc.c: 7621
+cb_das16_cs.c: 25977
+cbe_cpufreq.c: 4980
+cbe_cpufreq.h: 578
+cbe_cpufreq_pervasive.c: 2924
+cbe_cpufreq_pmi.c: 3695
+cbe_powerbutton.c: 3019
+cbe_regs.c: 6692
+cbe_thermal.c: 10724
+cb_pcidas64.c: 122559
+cb_pcidas.c: 54058
+cb_pcidda.c: 24298
+cb_pcidio.c: 9309
+cb_pcimdas.c: 14161
+cb_pcimdda.c: 15282
+cchips: 4096
+ccid2.c: 21699
+ccid2.h: 2480
+ccid3.c: 29348
+ccid3.h: 6401
+ccid.c: 5450
+ccid.h: 7568
+ccids: 4096
+ccio-dma.c: 48900
+ccio-rm-dma.c: 5203
+cciss.c: 121676
+cciss_cmd.h: 8834
+cciss.h: 7343
+cciss_ioctl.h: 6805
+cciss_scsi.c: 49769
+cciss_scsi.h: 3184
+cciss.txt: 6396
+ccm.c: 22059
+ccmd.c: 47173
+ccwdev.h: 6880
+ccwgroup.c: 16375
+ccwgroup.h: 2479
+cd1400.h: 7059
+cd1865.h: 13309
+cd32.txt: 535
+cda2df87ba4ecc7988be7a45d01645e11c9f4c: 307
+cdb89712.c: 5870
+cdc2.c: 6912
+cdc-acm.c: 43081
+cdc-acm.h: 3737
+cdc_eem.c: 9394
+cdc_ether.c: 17432
+cdc.h: 7100
+cdc_subset.c: 10970
+cdc-wdm.c: 19634
+cdefBF512.h: 1386
+cdefBF514.h: 5819
+cdefBF516.h: 16666
+cdefBF518.h: 16668
+cdefBF51x_base.h: 71524
+cdefBF522.h: 1386
+cdefBF525.h: 26762
+cdefBF527.h: 37609
+cdefBF52x_base.h: 71524
+cdefBF532.h: 48301
+cdefBF534.h: 124785
+cdefBF537.h: 13187
+cdefBF538.h: 148152
+cdefBF539.h: 16826
+cdefBF542.h: 35078
+cdefBF544.h: 59758
+cdefBF547.h: 48769
+cdefBF548.h: 98262
+cdefBF549.h: 115636
+cdefBF54x_base.h: 169306
+cdefBF561.h: 117485
+cdef_LPBlackfin.h: 20055
+cdev.c: 25135
+cdev.h: 677
+cdk.h: 12770
+cdrom: 4096
+cdrom.c: 99243
+cdrom.h: 36224
+cdrom-standard.tex: 51371
+cdrom.txt: 19223
+cds.txt: 21022
+ce6230.c: 8126
+ce6230.h: 2306
+ceiva.c: 7563
+cell: 4096
+cell.c: 9326
+cell_defconfig: 37867
+celleb_defconfig: 32091
+celleb_pci.c: 12369
+celleb_pci.h: 1402
+celleb_scc_epci.c: 10052
+celleb_scc.h: 7871
+celleb_scc_pciex.c: 15023
+celleb_scc_sio.c: 2600
+celleb_scc_uhc.c: 2518
+celleb_setup.c: 6097
+cell_edac.c: 7394
+cell-pmu.h: 4133
+cell-regs.h: 9211
+centaur.c: 5432
+central.c: 6181
+CERF: 1215
+cerf.c: 3449
+cerfcube_defconfig: 17978
+cerf.h: 810
+cerr-sb1.c: 16742
+cevt-bcm1480.c: 4444
+cevt-ds1287.c: 2833
+cevt-gt641xx.c: 3662
+cevt-r4k.c: 5115
+cevt-r4k.h: 1421
+cevt-sb1250.c: 4380
+cevt-smtc.c: 8920
+cevt-txx9.c: 5694
+cex-gen.S: 1009
+cex-oct.S: 1574
+cex-sb1.S: 4707
+cfag12864b: 3173
+cfag12864b.c: 8350
+cfag12864b-example.c: 5897
+cfag12864bfb.c: 4656
+cfag12864b.h: 2147
+cfbcopyarea.c: 11312
+cfbfillrect.c: 8940
+cfbimgblt.c: 8396
+cfe: 4096
+cfe_api.c: 11219
+cfe_api.h: 3833
+cfe_api_int.h: 4031
+cfe.c: 8423
+cfe_console.c: 1737
+cfe_error.h: 2197
+cfg80211.c: 10563
+cfg80211.h: 1079
+cfg.c: 35379
+cfg.h: 155
+cfi_cmdset_0001.c: 73671
+cfi_cmdset_0002.c: 53117
+cfi_cmdset_0020.c: 38615
+cfi_endian.h: 1238
+cfi_flagadm.c: 3947
+cfi.h: 13714
+cfi_probe.c: 11670
+cfi_util.c: 5934
+cfm.c: 16482
+cfq-iosched.c: 65456
+cfunc.c: 33674
+cfunc.h: 23021
+cg14.c: 15044
+cg3.c: 11707
+cg6.c: 22284
+cgroup.c: 95997
+cgroup_debug.c: 2057
+cgroup_freezer.c: 9146
+cgroup.h: 15604
+cgroups: 4096
+cgroupstats.h: 2155
+cgroupstats.txt: 1307
+cgroups.txt: 21831
+cgroup_subsys.h: 697
+ch341.c: 15479
+ch9.h: 24667
+chafsr.h: 9671
+chainiv.c: 8763
+changebit.S: 617
+ChangeLog: 18049
+CHANGELOG: 18049
+ChangeLog.1992-1997: 59954
+ChangeLog.arcmsr: 6754
+ChangeLog.history: 25741
+ChangeLog.ide-cd.1994-2004: 15586
+ChangeLog.ide-floppy.1996-2002: 4068
+ChangeLog.ide-tape.1995-2002: 16249
+ChangeLog.ips: 5304
+ChangeLog.lpfc: 89671
+ChangeLog.megaraid: 23975
+ChangeLog.megaraid_sas: 12624
+ChangeLog.ncr53c8xx: 22786
+ChangeLog.sym53c8xx: 29464
+ChangeLog.sym53c8xx_2: 6011
+Changes: 4725
+CHANGES: 4725
+chan_kern.c: 13142
+chan_kern.h: 1587
+chan_user.c: 7101
+chan_user.h: 1710
+char: 4096
+char_dev.c: 13712
+chb.c: 5975
+ch.c: 24601
+check-all.sh: 434
+check.c: 3835
+check-gas: 277
+check-gas-asm.S: 37
+check.h: 551
+checkincludes.pl: 529
+checkkconfigsymbols.sh: 1851
+checklist.c: 8211
+checklist.txt: 14315
+check-lxdialog.sh: 1653
+check-model.c: 47
+checkpatch.pl: 70566
+checkpoint.c: 21921
+checks.c: 15663
+check-segrel.lds: 203
+check-segrel.S: 45
+check-serialize.S: 41
+check.sh: 214
+check_signature.c: 599
+checkstack.pl: 5332
+checksum_32.h: 4895
+checksum_32.S: 4739
+checksum_64.h: 5349
+checksum_64.S: 6192
+checksum.c: 4610
+checksumcopy.S: 2455
+checksum.h: 6169
+checksum_mm.h: 3391
+checksum_no.h: 3074
+checksum.S: 9073
+checksyscalls.sh: 5661
+check-text-align.S: 69
+checkversion.pl: 1867
+chelsio: 4096
+cherrs.S: 15233
+chio.h: 5287
+chip.c: 15518
+chip.h: 5099
+chipram.c: 3350
+chipreg.c: 2405
+chips: 4096
+chipsfb.c: 12752
+chlist.h: 30
+chmc.c: 20666
+chmctrl.h: 8057
+chp.c: 17406
+chp.h: 1489
+chpid.h: 1040
+chrp: 4096
+chrp32_defconfig: 40160
+chrp.h: 308
+chsc.c: 22534
+chsc.h: 2470
+chsc_sch.c: 19838
+chsc_sch.h: 179
+chunk.c: 8172
+ci13xxx_udc.c: 69484
+ci13xxx_udc.h: 6227
+cia.c: 4343
+cicada.c: 3994
+cic.c: 14355
+cifs: 4096
+cif.S: 1000
+cifsacl.c: 21375
+cifsacl.h: 2405
+cifs_debug.c: 21856
+cifs_debug.h: 2329
+cifs_dfs_ref.c: 9982
+cifsencrypt.c: 12795
+cifsencrypt.h: 1256
+cifsfs.c: 31585
+cifsfs.h: 4854
+cifs_fs_sb.h: 2432
+cifsglob.h: 23265
+cifspdu.h: 81322
+cifsproto.h: 16968
+cifssmb.c: 173618
+cifs_spnego.c: 4357
+cifs_spnego.h: 1628
+cifs.txt: 2406
+cifs_unicode.c: 7190
+cifs_unicode.h: 8878
+cifs_uniupr.h: 12874
+cimax2.c: 11227
+cimax2.h: 1921
+cinergyT2-core.c: 6717
+cinergyT2-fe.c: 8456
+cinergyT2.h: 3001
+cinit.c: 59044
+cio: 4096
+cio.c: 27748
+cio_debug.h: 849
+cio.h: 4879
+cipher.c: 7783
+cipso_ipv4.c: 64343
+cipso_ipv4.h: 7616
+cipso_ipv4.txt: 2252
+circ_buf.h: 1000
+cirrusfb.c: 77607
+cirrusfb.txt: 1934
+cirrus.h: 8939
+cis: 4096
+ciscode.h: 3364
+cisreg.h: 2804
+cistpl.c: 38770
+cistpl.h: 14596
+ci.txt: 6753
+ck804xrom.c: 10948
+class: 4096
+class.c: 12662
+class_to_string.h: 1508
+class.txt: 4758
+claw.c: 115821
+claw.h: 14619
+clcd.c: 5668
+clcd.h: 6601
+cleanfile: 3492
+cleanpatch: 5132
+cleanup.c: 28008
+clearbit.S: 613
+clear_page_64.S: 969
+clear_page.S: 401
+clear_user.S: 2687
+clep7312.c: 1478
+client.c: 45575
+client.h: 7071
+clinkage.h: 27
+clip.c: 24997
+clk.c: 774
+clkdev.c: 3488
+clkdev.h: 122
+clkgen_defs_asm.h: 7393
+clkgen_defs.h: 5421
+clk.h: 4465
+clk_interface.h: 683
+clksupport.h: 844
+clk.txt: 1173
+clnt.c: 42336
+clnt.h: 5095
+clntlock.c: 6865
+clntproc.c: 21263
+clock24xx.c: 22943
+clock24xx.h: 82888
+clock34xx.c: 31225
+clock34xx.h: 84973
+clock-7x01a.c: 4770
+clock.c: 6387
+clockchips.h: 4535
+clock-cpg.c: 5839
+clock-dclk.c: 4423
+clockdomain.c: 16366
+clockdomain.h: 3231
+clockdomains.h: 9108
+clockevents.c: 6244
+clock_getres.S: 1020
+clock_gettime.S: 2948
+clock.h: 1320
+clock_imx21.c: 23302
+clock_imx27.c: 22042
+clock-imx35.c: 13016
+clocking.txt: 1582
+clocks.c: 2153
+clocks.h: 2092
+clock-sh3.c: 2204
+clock-sh4-202.c: 3818
+clock-sh4.c: 1967
+clock-sh5.c: 1848
+clock-sh7201.c: 1982
+clock-sh7203.c: 1936
+clock-sh7206.c: 1931
+clock-sh7343.c: 6574
+clock-sh7366.c: 6500
+clock-sh7619.c: 1741
+clock-sh7705.c: 2140
+clock-sh7706.c: 2055
+clock-sh7709.c: 2302
+clock-sh7710.c: 1874
+clock-sh7712.c: 1592
+clock-sh7722.c: 5683
+clock-sh7723.c: 7223
+clock-sh7724.c: 7654
+clock-sh7763.c: 2503
+clock-sh7770.c: 1749
+clock-sh7780.c: 2630
+clock-sh7785.c: 3792
+clock-sh7786.c: 3252
+clock-shx3.c: 2959
+clocks-init.c: 2524
+clocksource: 4096
+clocksource.c: 16881
+clocksource.h: 11531
+clock.txt: 2443
+clone.c: 1295
+clps7111.h: 5605
+clps711x.c: 13340
+clps711xfb.c: 10751
+cls_api.c: 14078
+cls_basic.c: 6522
+cls_cgroup.c: 6506
+cls_flow.c: 15621
+cls_fw.c: 8499
+cls_route.c: 12482
+cls_rsvp6.c: 768
+cls_rsvp.c: 761
+cls_rsvp.h: 14927
+cls_tcindex.c: 11961
+cls_u32.c: 16562
+cluster: 4096
+cluster.c: 14916
+cluster.h: 3649
+clut_vga16.ppm: 230
+cm109.c: 24186
+cm4000_cs.c: 50839
+cm4000_cs.h: 1822
+cm4040_cs.c: 17240
+cm4040_cs.h: 1435
+cm5200_defconfig: 30374
+cm5200.dts: 5770
+cm9780.h: 1648
+cma.c: 76031
+cmap_xfbdev.txt: 1927
+cm_bf527.c: 24357
+CM-BF527_defconfig: 33449
+cm_bf533.c: 10441
+CM-BF533_defconfig: 17784
+cm_bf537.c: 15825
+CM-BF537E_defconfig: 22519
+CM-BF537U_defconfig: 18739
+cm_bf548.c: 20079
+CM-BF548_defconfig: 31514
+cm_bf561.c: 11463
+CM-BF561_defconfig: 19376
+cmb.h: 2128
+cm.c: 108467
+cmd640.c: 22942
+cmd64x.c: 13588
+cmdblk.h: 1843
+cmd.c: 12040
+cmd.h: 3292
+cmdline.c: 774
+cmdlinepart.c: 9405
+cmdpkt.h: 4387
+cmdresp.c: 16004
+cmf.c: 34004
+cm.h: 3735
+CMI8330: 3229
+cmi8330.c: 22466
+cmipci.c: 104710
+CMIPCI.txt: 9357
+cmmap.c: 75502
+cmm.c: 74564
+cmm_data_2860.c: 34802
+cmm_data_2870.c: 28944
+cmm_data.c: 42
+cmm_info.c: 42
+cmm_sanity.c: 44
+cm_msgs.h: 21469
+cmmsta.c: 182636
+cmm_sync.c: 42
+cmm_wpa.c: 41
+cmode.S: 4744
+cmpdi2.c: 435
+cmp.h: 486
+cmpxchg_32.h: 9438
+cmpxchg_64.h: 4582
+cmpxchg.c: 1500
+cmpxchg-grb.h: 2053
+cmpxchg.h: 3173
+cmpxchg-irq.h: 796
+cmpxchg-llsc.h: 1420
+cmpxchg-local.h: 1369
+cm-regbits-24xx.h: 14321
+cm-regbits-34xx.h: 26454
+cm_sbs.c: 3007
+cmservice.c: 13501
+cmtdef.h: 23113
+cmt.h: 1786
+cmtp: 4096
+cmtp.h: 3099
+cmu.c: 5791
+cm-x255.c: 5295
+cm-x270.c: 7295
+cmx270_nand.c: 6063
+cm-x2xx.c: 11698
+cm_x2xx_defconfig: 48725
+cm-x2xx-pci.c: 5404
+cm-x2xx-pci.h: 460
+cm-x300.c: 11712
+cm_x300_defconfig: 39363
+cn_cifs.h: 1323
+cnic.c: 66079
+cnic_defs.h: 16086
+cnic.h: 7097
+cnic_if.h: 7270
+cnode.c: 4219
+cn_proc.c: 7019
+cn_proc.h: 3206
+cn_queue.c: 6122
+cnt32_to_63.h: 3193
+cn_test.c: 4483
+cnv_float.h: 13001
+coalesced_mmio.c: 3435
+coalesced_mmio.h: 652
+cobalt: 4096
+cobalt_btns.c: 4645
+cobalt_defconfig: 29161
+cobalt.h: 614
+cobalt_lcdfb.c: 7871
+cobra.c: 6747
+c-octeon.c: 7206
+coda: 4096
+coda_cache.h: 673
+coda_fs_i.h: 1700
+coda.h: 17708
+coda_int.h: 434
+coda_linux.c: 5125
+coda_linux.h: 2883
+coda_psdev.h: 3200
+coda.txt: 49725
+code16gcc.h: 388
+codecs: 12288
+codec.txt: 5826
+code-patching.c: 12715
+code-patching.h: 1744
+CodingStyle: 29820
+coff.h: 12413
+coh901327_wdt.c: 14160
+coid.c: 75657
+coldfire: 4096
+coldfire.h: 1492
+colibri.h: 1059
+colibri-pxa270.c: 3375
+colibri_pxa270_defconfig: 42182
+colibri-pxa300.c: 4795
+colibri_pxa300_defconfig: 27217
+colibri-pxa320.c: 4735
+colibri-pxa3xx.c: 3817
+collate.c: 3675
+collate.h: 1705
+collie.c: 7329
+collie_defconfig: 18902
+collie.h: 3779
+color.c: 4817
+color.h: 1187
+com20020.c: 10296
+com20020_cs.c: 10301
+com20020.h: 3624
+com20020-isa.c: 5185
+com20020-pci.c: 5701
+com90io.c: 11118
+com90xx.c: 18469
+comedi: 4096
+comedi_bond.c: 17048
+comedi_compat32.c: 17423
+comedi_compat32.h: 1861
+comedidev.h: 16882
+comedi_fc.c: 3317
+comedi_fc.h: 2462
+comedi_fops.c: 60764
+comedi_fops.h: 191
+comedi.h: 29999
+comedi_ksyms.c: 2407
+comedilib.h: 7998
+comedi_parport.c: 9181
+comedi_pci.h: 1605
+comedi_test.c: 14760
+command.c: 8449
+command.h: 8829
+command-list.txt: 288
+commands.c: 25775
+commands.h: 11936
+comm.c: 4950
+commctrl.c: 23882
+comminit.c: 13072
+commit.c: 32855
+commit-msg.sample: 894
+common: 4096
+common.c: 25712
+commoncap.c: 27617
+common_defconfig: 11971
+common.h: 12299
+CommonIO: 4651
+common.lds.S: 2212
+common-offsets.h: 1451
+common-pci.c: 12979
+common_perm_to_string.h: 1100
+common-smdk.c: 4474
+common-smdk.h: 451
+commproc.c: 8070
+commproc.h: 25607
+commsup.c: 51665
+CompactFlash: 1735
+compal-laptop.c: 8886
+comparator.h: 5271
+compartmentalisation.txt: 1944
+compat_audit.c: 664
+compat_binfmt_elf.c: 3496
+compat.c: 2196
+compat_exec_domain.c: 741
+compat.h: 369
+compatibility-list.txt: 1345
+compat_ioctl.c: 7581
+compat_ioctl.h: 4449
+compat_linux.c: 21127
+compat_linux.h: 7320
+compatmac.h: 332
+compat_mq.c: 4132
+compat_ptrace.h: 2572
+compat_rt_sigframe.h: 1846
+compat_signal.c: 17351
+compat_signal.h: 57
+compat-signal.h: 2664
+compat_ucontext.h: 552
+compat_wrapper.S: 48644
+compiler-gcc3.h: 823
+compiler-gcc4.h: 1407
+compiler-gcc.h: 3118
+compiler.h: 4524
+compiler-intel.h: 746
+completion.h: 3226
+composite.c: 30121
+composite.h: 14982
+compr.c: 10363
+compress.c: 1839
+compressed: 4096
+compress.h: 974
+compression.c: 18461
+compression.h: 1742
+compr.h: 3025
+compr_lzo.c: 2312
+compr_rtime.c: 2867
+compr_rubin.c: 8932
+compr_zlib.c: 5850
+computone.txt: 17570
+comstats.h: 3120
+con3215.c: 30319
+con3270.c: 15947
+concap.h: 3778
+concat.h: 454
+conditional.c: 11225
+conditional.h: 617
+conex.c: 32880
+conf.c: 11969
+confdata.c: 19322
+config: 2695
+config3270.sh: 2009
+config.c: 24033
+config.c.in: 496
+config_defs_asm.h: 5405
+config_defs.h: 4370
+configfs: 4096
+configfs_example_explicit.c: 12619
+configfs_example_macros.c: 11555
+configfs.h: 8837
+configfs_internal.h: 5080
+configfs.txt: 21464
+config.h: 1142
+config.mk: 7917
+config-osm.c: 2170
+config_roms.c: 4579
+config_roms.h: 588
+configs: 4096
+configs.c: 2818
+configuring.txt: 4139
+cong.c: 12223
+conmakehash.c: 6121
+connect.c: 38
+connection.c: 13263
+connector: 4096
+connector.c: 11327
+connector.h: 4405
+connector.txt: 6503
+conntrack.h: 810
+consistent.c: 3927
+console: 4096
+console_32.c: 2071
+console_64.c: 1575
+console.c: 7199
+console.h: 2080
+consolemap.c: 22885
+consolemap.h: 1029
+console_struct.h: 5109
+console.txt: 5814
+constants.c: 49479
+constants.h: 2939
+const.h: 596
+constraint.h: 2093
+consumer.h: 8894
+consumer.txt: 6869
+container.c: 7095
+container.h: 198
+contec_pci_dio.c: 5763
+context.c: 1678
+context.h: 3703
+context.S: 6412
+contig.c: 7791
+contregs.h: 3351
+CONTRIBUTORS: 495
+contributors.txt: 3035
+control.c: 43620
+control_compat.c: 11584
+controlfb.c: 27775
+controlfb.h: 4696
+control.h: 9928
+ControlNames.txt: 2085
+control_w.h: 1820
+cookie.c: 13149
+coprocessor.h: 5194
+coprocessor.S: 7277
+coproc.h: 362
+cops.c: 29453
+cops_ffdrv.h: 21384
+cops.h: 1400
+cops_ltdrv.h: 9491
+cops.txt: 2768
+copy_32.S: 9822
+copy.c: 2883
+copy_from_user.S: 1986
+COPYING: 18693
+COPYING.LIB: 25265
+copy_in_user.S: 1659
+copy_page_64.S: 2337
+copypage_64.S: 2011
+copypage-fa.c: 2349
+copypage-feroceon.c: 3145
+copy_page_mck.S: 5871
+copy_page.S: 532
+copypage-v3.c: 2110
+copypage-v4mc.c: 3649
+copypage-v4wb.c: 2820
+copypage-v4wt.c: 2403
+copypage-v6.c: 3822
+copypage-xsc3.c: 2840
+copypage-xscale.c: 3881
+copy.S: 1321
+copy_template.S: 5586
+copy_to_user.S: 2016
+copy_user_64.S: 5420
+copyuser_64.S: 9936
+copy_user_memcpy.S: 5245
+copy_user_nocache_64.S: 2468
+copy_user.S: 2573
+core: 4096
+core_apecs.c: 10176
+core_apecs.h: 17281
+coreb.c: 1844
+core.c: 24656
+core-card.c: 15330
+core-cdev.c: 37224
+core_cia.c: 33365
+core_cia.h: 15760
+core-device.c: 32375
+coredump.c: 5613
+core.h: 5921
+core_irongate.c: 10486
+core_irongate.h: 6754
+core-iso.c: 8971
+core_lca.c: 14096
+core_lca.h: 11596
+core_locking.txt: 4081
+core_marvel.c: 25082
+core_marvel.h: 9350
+core_mcpcia.c: 16238
+core_mcpcia.h: 11691
+core_polaris.c: 4523
+core_polaris.h: 2948
+core_priv.h: 1817
+core_t2.c: 16416
+core_t2.h: 20353
+coretemp: 1672
+coretemp.c: 11947
+core_titan.c: 20020
+core_titan.h: 11455
+core-topology.c: 15332
+core-transaction.c: 27218
+core_tsunami.c: 13148
+core_tsunami.h: 8469
+core.txt: 804
+core_wildfire.c: 17607
+core_wildfire.h: 8616
+corgi.c: 9471
+corgi_defconfig: 47365
+corgi.h: 4831
+corgikbd.c: 12406
+corgi_lcd.c: 16845
+corgi_lcd.h: 421
+corgi_pm.c: 7155
+corgi_ssp.c: 7384
+corgi_ts.c: 9648
+cosa.c: 59334
+cosa.h: 4349
+country.h: 4726
+cow.h: 1883
+cow_sys.h: 692
+cow_user.c: 12166
+coyote.h: 949
+coyote-pci.c: 1459
+coyote-setup.c: 3158
+cp1emu.c: 28793
+cp210x.c: 24866
+cp437.uni: 4426
+cp6.c: 1398
+cpc925_edac.c: 30540
+cpc.h: 16904
+cpci_hotplug_core.c: 17267
+cpci_hotplug.h: 3193
+cpci_hotplug_pci.c: 7823
+cpcihp_generic.c: 6519
+cpcihp_zt5550.c: 8619
+cpcihp_zt5550.h: 2730
+cpc_int.h: 2284
+cpcmd.c: 3087
+cpcmd.h: 1259
+cpc-usb: 4096
+cpc-usb_drv.c: 28935
+cpcusb.h: 2856
+cpfile.c: 24964
+cpfile.h: 1680
+cphy.h: 6427
+cpia2: 4096
+cpia2_core.c: 77737
+cpia2dev.h: 1919
+cpia2.h: 13192
+cpia2_overview.txt: 2357
+cpia2_registers.h: 17890
+cpia2_usb.c: 25426
+cpia2_v4l.c: 50779
+cpia.c: 114212
+cpia.h: 11791
+cpia_pp.c: 22139
+cpia_usb.c: 16084
+cp_intc.c: 3984
+cp_intc.h: 2302
+cpl5_cmd.h: 12577
+cplb.h: 4597
+cplbinfo.c: 3920
+cplbinit.c: 3353
+cplbinit.h: 2491
+cplbmgr.c: 9975
+cplb-mpu: 4096
+cplb-nompu: 4096
+cpm: 4096
+cpm1.c: 19027
+cpm1.h: 23000
+cpm2.c: 8657
+cpm2.h: 51335
+cpm2_pic.c: 7028
+cpm2_pic.h: 177
+cpmac.c: 35475
+cpm_common.c: 8715
+cpm.h: 3601
+cpm_qe: 4096
+cpm-serial.c: 5276
+cpm.txt: 2279
+cpm_uart: 4096
+cpm_uart_core.c: 34184
+cpm_uart_cpm1.c: 4062
+cpm_uart_cpm1.h: 630
+cpm_uart_cpm2.c: 4728
+cpm_uart_cpm2.h: 692
+cpm_uart.h: 3846
+cppi_dma.c: 44672
+cppi_dma.h: 3257
+cpqarray.c: 48267
+cpqarray.h: 3023
+cpqarray.txt: 2224
+cpqphp_core.c: 37277
+cpqphp_ctrl.c: 77860
+cpqphp.h: 22122
+cpqphp_nvram.c: 13820
+cpqphp_nvram.h: 1534
+cpqphp_pci.c: 39788
+cpqphp_sysfs.c: 5682
+cprecomp.h: 1072
+cpsmgr.c: 18525
+cpu: 4096
+cpu5wdt.c: 6940
+cpuacct.txt: 1941
+cpu_buffer.c: 11402
+cpu_buffer.h: 2876
+cpu-bugs64.c: 7627
+cpu.c: 5945
+cpucheck.c: 6054
+cpu-common: 4096
+cpudata_32.h: 574
+cpudata_64.h: 1041
+cpudata.h: 184
+cpu_debug.c: 17937
+cpu_debug.h: 3759
+cpu-drivers.txt: 7387
+cpufeature.h: 13827
+cpu-feature-overrides.h: 1176
+cpu-features.h: 7307
+cpu_features.txt: 2681
+cpufreq: 4096
+cpu-freq: 4096
+cpufreq_32.c: 18804
+cpufreq_64.c: 20116
+cpufreq.c: 49742
+cpufreq_conservative.c: 18026
+cpu-freq.h: 2392
+cpufreq.h: 12164
+cpufreq-nforce2.c: 9537
+cpufreq-nforce2.txt: 597
+cpufreq_ondemand.c: 19342
+cpufreq_performance.c: 1553
+cpufreq_powersave.c: 1625
+cpufreq-pxa2xx.c: 14833
+cpufreq-pxa3xx.c: 6493
+cpufreq_spudemand.c: 4449
+cpufreq_stats.c: 9729
+cpufreq-stats.txt: 5021
+cpufreq_userspace.c: 6109
+cpu.h: 1297
+cpu-h7201.c: 1510
+cpu-h7202.c: 5243
+cpu_hotplug.c: 2052
+cpu-hotplug-spec: 1155
+cpu-hotplug.txt: 14935
+cpuid.c: 5549
+cpuid.h: 617
+cpuidle: 4096
+cpuidle.c: 8664
+cpuidle.h: 1058
+cpu_imx27.c: 1739
+cpuinfo.c: 2141
+cpu-info.h: 2924
+cpuinfo.h: 2135
+cpuinfo-pvr-full.c: 2822
+cpuinfo-static.c: 4940
+cpu-irqs.h: 2654
+cpu-load.txt: 3110
+cpumap.c: 10894
+cpumap.h: 320
+cpumask.c: 4643
+cpumask.h: 381
+cpu-multi32.h: 1743
+cpu-omap.c: 4053
+cpu-probe.c: 23180
+cpu-regs.h: 14601
+cpu-sa1100.c: 7866
+cpu-sa1110.c: 9518
+cpuset.c: 72697
+cpuset.h: 4740
+cpusets.txt: 36191
+cpu_setup_44x.S: 1639
+cpu_setup_6xx.S: 11167
+cpu_setup_fsl_booke.S: 1766
+cpu_setup_pa6t.S: 1218
+cpu_setup_ppc970.S: 3704
+cpu-sh2: 4096
+cpu-sh2a: 4096
+cpu-sh3: 4096
+cpu-sh4: 4096
+cpu-sh5: 4096
+cpu-single.h: 1429
+cputable.c: 57765
+cputable.h: 19753
+cputhreads.h: 1572
+cputime.h: 118
+cputopology.txt: 3013
+cputype.h: 840
+cpu_vect.h: 1321
+cp_vers.h: 933
+cpwd.c: 16512
+cq.c: 20469
+c-qcam.c: 19812
+CQcam.txt: 7069
+cq_desc.h: 2507
+cq_enet_desc.h: 6342
+cq_exch_desc.h: 5837
+cq.h: 4130
+c-r3k.c: 8056
+c-r4k.c: 37720
+cramfs: 4096
+cramfs_fs.h: 2930
+cramfs_fs_sb.h: 343
+cramfs.txt: 2599
+crash.c: 9898
+crash_dump_32.c: 2149
+crash_dump_64.c: 1417
+crash_dump.c: 3851
+crash_dump.h: 2002
+cr_bllcd.c: 7402
+crc16.c: 2838
+crc16.h: 622
+crc32.c: 15299
+crc32c.c: 8200
+crc32c.h: 254
+crc32c-intel.c: 4975
+crc32defs.h: 1072
+crc32.h: 880
+crc32hash.c: 654
+crc7.c: 2329
+crc7.h: 272
+crc-ccitt.c: 3052
+crc-ccitt.h: 330
+crc.h: 880
+crc-itu-t.c: 2892
+crc-itu-t.h: 615
+crc-t10dif.c: 2965
+crc-t10dif.h: 140
+cred.c: 14888
+credentials.txt: 20932
+cred.h: 10905
+cred-internals.h: 559
+CREDITS: 603
+crime.c: 2833
+crime.h: 5271
+cris: 4096
+cris_defs_asm.h: 3805
+crisksyms.c: 472
+cris_supp_reg.h: 198
+crisv10.c: 129158
+crisv10.h: 4289
+crm_regs.h: 1700
+cr_pll.c: 4842
+crt0_ram.S: 2152
+crt0_rom.S: 3157
+crt0.S: 1979
+crtsavres.S: 6123
+crunch-bits.S: 8521
+crunch.c: 2001
+crw.c: 4007
+crw.h: 2025
+cryptd.c: 16974
+cryptd.h: 650
+crypto: 4096
+crypto4xx_alg.c: 8383
+crypto4xx_core.c: 34847
+crypto4xx_core.h: 5634
+crypto4xx_reg_def.h: 7646
+crypto4xx_sa.c: 2984
+crypto4xx_sa.h: 5742
+crypto.c: 16089
+crypto_compat.h: 2294
+cryptocop.c: 111134
+cryptocop.h: 7614
+crypto_des.h: 516
+crypto.h: 35141
+cryptohash.h: 264
+cryptoloop.c: 5005
+crypto_null.c: 5051
+crypto_wq.c: 896
+crypto_wq.h: 122
+crypt_s390.h: 10190
+cs4231.c: 6021
+cs4231-regs.h: 8547
+cs4236.c: 22848
+cs4236_lib.c: 35470
+cs423x: 4096
+cs4270.c: 26832
+cs4270.h: 804
+cs4281.c: 66411
+cs4362a.h: 2039
+cs4398.h: 1968
+cs461x.txt: 2184
+cs46xx: 4096
+cs46xx.c: 5301
+cs46xx_dsp_scb_types.h: 28137
+cs46xx_dsp_spos.h: 6198
+cs46xx_dsp_task_types.h: 7293
+cs46xx.h: 73681
+cs46xx_image.h: 155782
+cs46xx_lib.c: 107227
+cs46xx_lib.h: 8586
+cs5345.c: 5839
+cs5345.h: 1210
+cs53l32a.c: 5932
+cs53l32a.h: 1196
+cs5520.c: 4777
+cs5530.c: 8332
+cs5535audio: 4096
+cs5535audio.c: 10538
+cs5535audio.h: 4162
+cs5535audio_olpc.c: 4595
+cs5535audio_pcm.c: 13419
+cs5535audio_pm.c: 4043
+cs5535.c: 6298
+cs5535_gpio.c: 6000
+cs5536.c: 7861
+cs553x_nand.c: 10268
+cs8403.h: 8833
+cs8420.h: 1681
+cs8427.c: 18610
+cs8427.h: 10572
+cs89712.h: 1848
+cs89x0.c: 59868
+cs89x0.h: 16242
+cs89x0.txt: 25508
+csb337_defconfig: 28177
+csb637_defconfig: 29026
+csb701.c: 1321
+csb726.c: 7527
+csb726.h: 658
+cs.c: 21706
+cscanmgr.c: 14014
+cs.h: 6099
+cs_internal.h: 7245
+csr1212.c: 38810
+csr1212.h: 14571
+csr.c: 26430
+csrc-bcm1480.c: 1705
+csrc-ioasic.c: 1796
+csrc-octeon.c: 1473
+csrc-r4k.c: 885
+csrc-sb1250.c: 2176
+csr.h: 2690
+css.c: 26134
+css.h: 4460
+cstate.c: 4904
+cs_types.h: 934
+csum-copy_64.S: 4160
+csum_copy_from_user.S: 439
+csum_copy.S: 7018
+csum_copy_to_user.S: 431
+csumcpfruser.S: 1663
+csum_ipv6_magic.S: 2885
+csumipv6.S: 696
+csum-partial_64.c: 3530
+csum_partial_copy.c: 8909
+csum_partial_copy_generic.S: 1729
+csumpartialcopygeneric.S: 6850
+csumpartialcopy.S: 1151
+csumpartialcopyuser.S: 2378
+csum_partial.S: 16737
+csumpartial.S: 3126
+csum-wrappers_64.c: 3926
+ct20k1reg.h: 20603
+ct20k2reg.h: 3088
+ct82c710.c: 6778
+ctamixer.c: 10033
+ctamixer.h: 2795
+ctatc.c: 42227
+ctatc.h: 5058
+ctcm_dbug.c: 1932
+ctcm_dbug.h: 3316
+ctcm_fsms.c: 75291
+ctcm_fsms.h: 8271
+ctcm_main.c: 45768
+ctcm_main.h: 6938
+ctcm_mpc.c: 59919
+ctcm_mpc.h: 5324
+ctcm_sysfs.c: 5171
+ctdaio.c: 17904
+ctdaio.h: 3291
+cthardware.c: 1688
+cthardware.h: 7286
+cthw20k1.c: 49680
+cthw20k1.h: 598
+cthw20k2.c: 49114
+cthw20k2.h: 598
+ctimap.c: 2516
+ctimap.h: 1167
+ctkip.c: 17399
+ctl_unnumbered.txt: 962
+ctmixer.c: 28786
+ctmixer.h: 1691
+ctpcm.c: 11244
+ctpcm.h: 612
+ctr.c: 11026
+ctree.c: 111552
+ctree.h: 75158
+ctresource.c: 5825
+ctresource.h: 2267
+ctr.h: 524
+ctrlchar.c: 1752
+ctrlchar.h: 484
+cts.c: 10045
+ctsrc.c: 19870
+ctsrc.h: 4527
+cttimer.c: 11342
+cttimer.h: 686
+ctvmem.c: 5666
+ctvmem.h: 1787
+c-tx39.c: 10852
+ctxfi: 4096
+ctxrx.c: 147975
+ctype.c: 1041
+ctype.h: 1399
+cu3088.c: 3577
+cu3088.h: 848
+cuboot-52xx.c: 1660
+cuboot-824x.c: 1224
+cuboot-83xx.c: 1525
+cuboot-85xx.c: 1673
+cuboot-85xx-cpm2.c: 1764
+cuboot-8xx.c: 1149
+cuboot-acadia.c: 4964
+cuboot-amigaone.c: 868
+cuboot-bamboo.c: 689
+cuboot.c: 944
+cuboot-c2k.c: 4884
+cuboot-ebony.c: 782
+cuboot.h: 365
+cuboot-katmai.c: 1294
+cuboot-mpc7448hpc2.c: 1279
+cuboot-pq2.c: 7138
+cuboot-rainier.c: 1453
+cuboot-sam440ep.c: 1254
+cuboot-sequoia.c: 1453
+cuboot-taishan.c: 1361
+cuboot-warp.c: 916
+cuboot-yosemite.c: 1095
+cuda.h: 978
+cumana_1.c: 7960
+cumana_2.c: 14690
+current.h: 677
+cuse.c: 14893
+cvisionppc.h: 1577
+cvmx-address.h: 8499
+cvmx-asm.h: 4526
+cvmx-asxx-defs.h: 14223
+cvmx-bootinfo.h: 9081
+cvmx-bootmem.c: 20524
+cvmx-bootmem.h: 12982
+cvmx-ciu-defs.h: 39090
+cvmx-cmd-queue.c: 9400
+cvmx-cmd-queue.h: 18993
+cvmx-config.h: 6486
+cvmx-dbg-defs.h: 2123
+cvmx-fau.h: 19011
+cvmx-fpa.c: 4975
+cvmx-fpa-defs.h: 11938
+cvmx-fpa.h: 8284
+cvmx-gmxx-defs.h: 79305
+cvmx-gpio-defs.h: 6346
+cvmx.h: 14240
+cvmx-helper-board.c: 21950
+cvmx-helper-board.h: 6656
+cvmx-helper.c: 32770
+cvmx-helper-errata.c: 2592
+cvmx-helper-errata.h: 1277
+cvmx-helper-fpa.c: 7545
+cvmx-helper-fpa.h: 2360
+cvmx-helper.h: 7482
+cvmx-helper-jtag.c: 4203
+cvmx-helper-jtag.h: 1530
+cvmx-helper-loop.c: 2679
+cvmx-helper-loop.h: 1901
+cvmx-helper-npi.c: 3413
+cvmx-helper-npi.h: 1897
+cvmx-helper-rgmii.c: 17448
+cvmx-helper-rgmii.h: 3560
+cvmx-helper-sgmii.c: 17037
+cvmx-helper-sgmii.h: 3417
+cvmx-helper-spi.c: 6088
+cvmx-helper-spi.h: 2785
+cvmx-helper-util.c: 12555
+cvmx-helper-util.h: 6164
+cvmx-helper-xaui.c: 11997
+cvmx-helper-xaui.h: 3409
+cvmx-interrupt-decodes.c: 13959
+cvmx-interrupt-rsl.c: 3787
+cvmx-iob-defs.h: 16589
+cvmx-ipd-defs.h: 27302
+cvmx-ipd.h: 10763
+cvmx-l2c.c: 19669
+cvmx-l2c-defs.h: 23395
+cvmx-l2c.h: 10068
+cvmx-l2d-defs.h: 9721
+cvmx-l2t-defs.h: 3720
+cvmx-led-defs.h: 6731
+cvmx-mdio.h: 13085
+cvmx-mio-defs.h: 54538
+cvmx-npei-defs.h: 61528
+cvmx-npi-defs.h: 46348
+cvmx-packet.h: 1964
+cvmx-pci-defs.h: 40401
+cvmx-pcieep-defs.h: 32743
+cvmx-pciercx-defs.h: 36139
+cvmx-pcsx-defs.h: 11497
+cvmx-pcsxx-defs.h: 9562
+cvmx-pescx-defs.h: 11439
+cvmx-pexp-defs.h: 9365
+cvmx-pip-defs.h: 34993
+cvmx-pip.h: 16579
+cvmx-pko.c: 14987
+cvmx-pko-defs.h: 31966
+cvmx-pko.h: 18946
+cvmx-pow-defs.h: 19069
+cvmx-pow.h: 59817
+cvmx-scratch.h: 3875
+cvmx-smix-defs.h: 5173
+cvmx-spi.c: 22343
+cvmx-spi.h: 9516
+cvmx-spinlock.h: 6516
+cvmx-spxx-defs.h: 9687
+cvmx-srxx-defs.h: 3849
+cvmx-stxx-defs.h: 8491
+cvmx-sysinfo.c: 3570
+cvmx-sysinfo.h: 4893
+cvmx-wqe.h: 11943
+cwc4630.h: 15478
+cwcasync.h: 7969
+cwcbinhack.h: 1566
+cwcdma.asp: 4526
+cwcdma.h: 2174
+cwcsnoop.h: 1513
+cwep.c: 9662
+cwm.c: 3787
+cwm.h: 2421
+cx18: 4096
+cx18-audio.c: 2589
+cx18-audio.h: 905
+cx18-av-audio.c: 14932
+cx18-av-core.c: 41048
+cx18-av-core.h: 13381
+cx18-av-firmware.c: 7225
+cx18-av-vbi.c: 9043
+cx18-cards.c: 16165
+cx18-cards.h: 4838
+cx18-controls.c: 9435
+cx18-controls.h: 1257
+cx18-driver.c: 35409
+cx18-driver.h: 23311
+cx18-dvb.c: 9950
+cx18-dvb.h: 946
+cx18-fileops.c: 21082
+cx18-fileops.h: 1421
+cx18-firmware.c: 14987
+cx18-firmware.h: 1001
+cx18-gpio.c: 9268
+cx18-gpio.h: 1226
+cx18-i2c.c: 8776
+cx18-i2c.h: 1083
+cx18-io.c: 2807
+cx18-ioctl.c: 27533
+cx18-ioctl.h: 1423
+cx18-io.h: 4951
+cx18-irq.c: 2319
+cx18-irq.h: 1417
+cx18-mailbox.c: 21623
+cx18-mailbox.h: 3643
+cx18-queue.c: 6955
+cx18-queue.h: 2294
+cx18-scb.c: 5787
+cx18-scb.h: 7441
+cx18-streams.c: 21499
+cx18-streams.h: 1889
+cx18.txt: 811
+cx18-vbi.c: 7419
+cx18-vbi.h: 1031
+cx18-version.h: 1319
+cx18-video.c: 1080
+cx18-video.h: 875
+cx22700.c: 11029
+cx22700.h: 1488
+cx22702.c: 14516
+cx22702.h: 1673
+cx231xx: 4096
+cx231xx-audio.c: 14952
+cx231xx-avcore.c: 77231
+cx231xx-cards.c: 23257
+cx231xx-conf-reg.h: 25445
+cx231xx-core.c: 30779
+cx231xx-dvb.c: 13339
+cx231xx.h: 22018
+cx231xx-i2c.c: 12912
+cx231xx-input.c: 6423
+cx231xx-pcb-cfg.c: 20991
+cx231xx-pcb-cfg.h: 6456
+cx231xx-reg.h: 67462
+cx231xx-vbi.c: 17757
+cx231xx-vbi.h: 2261
+cx231xx-video.c: 58825
+cx23418.h: 17951
+cx2341x: 4096
+cx2341x.c: 38287
+cx2341x.h: 7383
+cx23885: 4096
+cx23885-417.c: 48981
+cx23885-cards.c: 25645
+cx23885-core.c: 54422
+cx23885-dvb.c: 26635
+cx23885.h: 16143
+cx23885-i2c.c: 9910
+cx23885-reg.h: 12999
+cx23885-vbi.c: 6762
+cx23885-video.c: 40258
+cx24110.c: 20853
+cx24110.h: 1810
+cx24113.c: 14661
+cx24113.h: 1673
+cx24116.c: 40768
+cx24116.h: 1706
+cx24123.c: 30243
+cx24123.h: 1979
+cx25840: 4096
+cx25840-audio.c: 11073
+cx25840-core.c: 45706
+cx25840-core.h: 3605
+cx25840-firmware.c: 3889
+cx25840.h: 3250
+cx25840-vbi.c: 7108
+cx88: 4096
+cx88-alsa.c: 23036
+cx88-blackbird.c: 39031
+cx88-cards.c: 89130
+cx88-core.c: 31343
+cx88-dsp.c: 8787
+cx88-dvb.c: 39095
+cx88.h: 22857
+cx88-i2c.c: 5568
+cx88-input.c: 14002
+cx88-mpeg.c: 24270
+cx88-reg.h: 34334
+cx88-tvaudio.c: 28674
+cx88-vbi.c: 6438
+cx88-video.c: 56637
+cx88-vp3054-i2c.c: 4322
+cx88-vp3054-i2c.h: 1559
+cxacru.c: 37008
+cxacru.txt: 2325
+cxgb2.c: 38481
+cxgb3: 4096
+cxgb3_ctl_defs.h: 5067
+cxgb3_defs.h: 3489
+cxgb3i: 4096
+cxgb3i_ddp.c: 20593
+cxgb3i_ddp.h: 8254
+cxgb3i.h: 4401
+cxgb3i_init.c: 3040
+cxgb3i_iscsi.c: 27545
+cxgb3_ioctl.h: 3847
+cxgb3i_offload.c: 50331
+cxgb3i_offload.h: 7277
+cxgb3i_pdu.c: 12368
+cxgb3i_pdu.h: 1710
+cxgb3i.txt: 3295
+cxgb3_main.c: 84313
+cxgb3_offload.c: 37599
+cxgb3_offload.h: 6272
+cxgb.txt: 13829
+cxio_dbg.c: 5114
+cxio_hal.c: 38094
+cxio_hal.h: 7482
+cxio_resource.c: 9188
+cxio_resource.h: 3116
+cxio_wr.h: 20826
+cxusb.c: 48202
+cxusb.h: 724
+cy82c693.c: 10524
+cyber2000fb.c: 43356
+cyber2000fb.h: 16008
+cyberjack.c: 14547
+cyclades.c: 158213
+cyclades.h: 24974
+cyclomx.h: 2544
+cyclone.c: 3125
+cyclone.h: 403
+cycx_cfm.h: 2926
+cycx_drv.c: 15649
+cycx_drv.h: 2183
+cycx_main.c: 9413
+cycx_x25.c: 45814
+cycx_x25.h: 3727
+cylinder.c: 5848
+cypress_atacb.c: 8391
+cypress_cy7c63.c: 7689
+cypress.h: 2856
+cypress_m8.c: 47071
+cypress_m8.h: 2367
+cyrix.c: 5962
+cytherm.c: 11260
+d101m_ucode.bin.ihex: 1675
+d101s_ucode.bin.ihex: 1675
+d102e_ucode.bin.ihex: 1675
+da9030_battery.c: 16256
+da9034-ts.c: 9057
+da903x_bl.c: 4988
+da903x.c: 13455
+da903x.h: 7048
+dabusb: 4096
+dabusb.c: 22084
+dabusb.h: 1873
+DAC960.c: 265715
+DAC960.h: 151800
+daca.c: 7036
+dac.h: 752
+dadapter.c: 14853
+dadapter.h: 1070
+daemon.c: 16879
+daemon.h: 8435
+daemon_kern.c: 2419
+daemon_user.c: 4368
+daisy.c: 12538
+DAI.txt: 2270
+dapm.txt: 10267
+daqboard2000.c: 25750
+darla20.c: 2889
+darla20_dsp.c: 3479
+darla24.c: 3153
+darla24_dsp.c: 3845
+dart.h: 2235
+dart_iommu.c: 10816
+das08.c: 26325
+das08_cs.c: 14893
+das08.h: 2561
+das16.c: 44853
+das16m1.c: 21006
+das1800.c: 48894
+das6402.c: 8510
+das800.c: 24454
+DASD: 3388
+dasd_3990_erp.c: 68376
+dasd_alias.c: 26580
+dasd.c: 72767
+dasd_devmap.c: 29631
+dasd_diag.c: 17829
+dasd_diag.h: 2628
+dasd_eckd.c: 95322
+dasd_eckd.h: 11295
+dasd_eer.c: 20468
+dasd_erp.c: 4866
+dasd_fba.c: 17801
+dasd_fba.h: 1816
+dasd_genhd.c: 4783
+dasd.h: 11124
+dasd_int.h: 21917
+dasd_ioctl.c: 11160
+dasd_proc.c: 9802
+data.c: 2497
+datafab.c: 20690
+datagram.c: 4449
+data-integrity.txt: 13815
+datalink.h: 482
+datapage.S: 2018
+datarate.c: 12551
+datarate.h: 2494
+datastream.c: 15931
+datastream.h: 514
+dat.c: 11476
+dat.h: 2048
+davicom.c: 4985
+davinci: 4096
+davinci_all_defconfig: 43899
+davinci.c: 13768
+davinci_emac.c: 84968
+davinci-evm.c: 6719
+davinci.h: 3430
+davinci-i2s.c: 17146
+davinci-i2s.h: 495
+davinci_nand.c: 23119
+davinci-pcm.c: 10560
+davinci-pcm.h: 783
+davinci-sffsdr.c: 4374
+davinci_wdt.c: 6690
+db1000_defconfig: 23355
+db1100_defconfig: 23611
+db1200_defconfig: 25180
+db1200.h: 6115
+db1500_defconfig: 30453
+db1550_defconfig: 26655
+db1x00: 4096
+db1x00.h: 5353
+db78x00-bp-setup.c: 2591
+db88f5281-setup.c: 9805
+db88f6281-bp-setup.c: 2227
+db9.c: 21255
+dbdma2.c: 10987
+dbdma.c: 29134
+dbdma.h: 3834
+dbell.c: 1075
+dbell.h: 1308
+dbg.c: 7231
+dbg_current.S: 402
+dbg.h: 144
+dbg_io.c: 5088
+dbg_stackcheck.S: 427
+dbg_stackkill.S: 575
+dbl_float.h: 36770
+dbox2-flash.c: 2719
+dbri.c: 80387
+dbus_contexts: 195
+dc21285.c: 5936
+dc21285-timer.c: 1332
+dc232b: 4096
+dc395x.c: 145696
+dc395x.h: 25842
+dc395x.txt: 3337
+dca: 4096
+dcache.c: 60424
+dcache.h: 2009
+dca-core.c: 6864
+dca.h: 2530
+dca-sysfs.c: 2700
+dcb: 4096
+dcbnl.c: 29597
+dcbnl.h: 11558
+dccp: 4096
+dccp.h: 15873
+dccp.txt: 7484
+dcdbas.c: 16163
+dcdbas.h: 2821
+dcdbas.txt: 3709
+dcookies.c: 6936
+dcookies.h: 1289
+dcore.c: 21748
+dcr.c: 6132
+dcr-generic.h: 1621
+dcr.h: 6308
+dcr-low.S: 983
+dcr-mmio.h: 1838
+dcr-native.h: 4500
+dcr-regs.h: 5140
+dcssblk.c: 27372
+dcu.h: 1481
+dd.c: 9413
+ddp.c: 49018
+ddr2_defs_asm.h: 11790
+ddr2_defs.h: 9835
+ddr.h: 4564
+de2104x.c: 54503
+de4x5.c: 169230
+de4x5.h: 49229
+de4x5.txt: 8677
+de600.c: 13275
+de600.h: 5588
+de620.c: 26654
+de620.h: 4970
+deadline-iosched.c: 11700
+deadline-iosched.txt: 2841
+debug-8250.S: 719
+debug.c: 7221
+debug-cmd.h: 1653
+debug-devices.c: 1975
+debugfs: 4096
+debug_fs.c: 16621
+debugfs.c: 6192
+debugfs.h: 2563
+debugfs_key.c: 9097
+debugfs_key.h: 1348
+debugfs-kmemtrace: 2769
+debugfs_netdev.c: 14895
+debugfs_netdev.h: 739
+debugfs-pktcdvd: 448
+debugfs_sta.c: 7063
+debugfs_sta.h: 427
+debugfs.txt: 7128
+debugging: 1594
+Debugging390.txt: 97243
+debugging-modules.txt: 954
+debugging-via-ohci1394.txt: 7635
+debug.h: 1195
+Debug.h: 1195
+debug_if.h: 3572
+debug-leds.c: 7120
+debug-levels.h: 1482
+debuglib.c: 4523
+debuglib.h: 11740
+debug_locks.c: 1127
+debug_locks.h: 1663
+debug-macro.S: 619
+debugobjects.c: 24352
+debugobjects.h: 2960
+debugobjects.tmpl: 14144
+debug-pagealloc.c: 2607
+debug-pl01x.S: 693
+debugport.c: 12453
+debugreg.h: 2904
+debug.S: 2650
+debug-stub.c: 6089
+debugtraps.S: 1210
+debug.txt: 5755
+dec: 4096
+dec21285.h: 5572
+dec_and_lock.c: 809
+decbin.S: 15728
+declance.c: 35842
+decl.h: 2409
+decnet: 4096
+decnet.txt: 10805
+decodecode: 1702
+decode_exc.c: 11585
+decode_rs.c: 6959
+decompress: 4096
+decompress_bunzip2.c: 23556
+decompress.c: 1126
+decompress_inflate.c: 3544
+decompress_unlzma.c: 15528
+decompress_v10.lds: 342
+decompress_v32.lds: 337
+decstation_defconfig: 17956
+dectypes.h: 427
+default_defconfig: 39014
+defBF512.h: 1271
+defBF514.h: 13406
+defBF516.h: 46402
+defBF518.h: 48358
+defBF51x_base.h: 113540
+defBF522.h: 1271
+defBF525.h: 44639
+defBF527.h: 77635
+defBF52x_base.h: 116393
+defBF532.h: 74150
+defBF534.h: 189790
+defBF537.h: 35002
+defBF539.h: 212777
+defBF542.h: 58060
+defBF544.h: 57371
+defBF547.h: 78333
+defBF548.h: 117603
+defBF549.h: 180941
+defBF54x_base.h: 251535
+defBF561.h: 109277
+defconfig: 20414
+deferred_io.txt: 3031
+defines.h: 5063
+define_trace.h: 1988
+defkeymap.c: 6243
+defkeymap.c_shipped: 11007
+defkeymap.map: 12183
+deflate.c: 5615
+deflate_syms.c: 377
+def_LPBlackfin.h: 29239
+defpalo.conf: 789
+defs.h: 12522
+deftree.c: 40510
+defutil.h: 11891
+defxx.c: 116343
+defxx.h: 54496
+delay_32.h: 882
+delay_64.h: 378
+delay-accounting.txt: 3837
+delayacct.c: 5038
+delayacct.h: 4108
+delay.c: 581
+delayed-ref.c: 24860
+delayed-ref.h: 6619
+delay.h: 1166
+delay_mm.h: 1362
+delay_no.h: 2314
+delay.S: 1279
+delay.txt: 694
+delegation.c: 14100
+delegation.h: 2261
+delkin_cb.c: 4687
+dell-laptop.c: 9519
+dell_rbu.c: 19420
+dell_rbu.txt: 4973
+dell-wmi.c: 6724
+delta.c: 23513
+delta.h: 5823
+demo_main.c: 29367
+demux.h: 8791
+denormal.c: 3335
+dentry.c: 2934
+dentry-locking.txt: 8359
+depca.c: 61475
+depca.h: 6823
+depca.txt: 1245
+desc.c: 19546
+desc_defs.h: 2385
+desc.h: 20526
+des_check_key.c: 4011
+descore-readme.txt: 17200
+description: 73
+des_generic.c: 36210
+des.h: 403
+design_notes.txt: 4626
+design.txt: 17558
+des_s390.c: 17966
+dev-audio.c: 1656
+devboards: 4096
+dev.c: 16990
+devconnect.c: 33409
+devdma.c: 2008
+devdma.h: 271
+development-process: 4096
+dev-fb.c: 1681
+devfs: 459
+dev.h: 9111
+dev-hsmmc1.c: 1647
+dev-hsmmc.c: 1640
+dev-i2c0.c: 1622
+dev-i2c1.c: 1587
+device.c: 3904
+device_cfg.h: 2924
+device_cgroup.c: 12005
+device_cgroup.h: 380
+device-drivers.tmpl: 13872
+device_fsm.c: 34071
+device.h: 31245
+device_handler: 4096
+device_id.c: 8750
+device_id.h: 9158
+device-init.c: 23541
+deviceiobook.tmpl: 11288
+device_main.c: 128828
+device-mapper: 4096
+device-mapper.h: 10956
+device_ops.c: 22502
+device_pgid.c: 16031
+devices: 4096
+devices.c: 19482
+devices.h: 918
+devices-rsk7203.c: 2587
+device_status.c: 12596
+devices.txt: 118144
+devicetable.txt: 1298
+device.txt: 6393
+devinet.c: 40642
+dev-interface: 8905
+devio.c: 45517
+dev-ioctl.c: 18582
+devmap.c: 1464
+dev_mcast.c: 5650
+devops_32.c: 1879
+devops_64.c: 1006
+devpts: 4096
+devpts_fs.h: 1454
+devpts.txt: 5085
+devres.c: 16191
+devres.txt: 7761
+devs.c: 9766
+devs.h: 1960
+dev-sysfs.c: 3852
+dev_table.c: 5563
+dev_table.h: 10908
+devtree.c: 8324
+dev-uart.c: 3521
+dev-usb.c: 1134
+dev-usb-hsotg.c: 992
+dfadd.c: 15801
+dfcmp.c: 5306
+dfdiv.c: 12636
+dfifo.h: 2160
+dfmpy.c: 11736
+dfrem.c: 8997
+dfs.c: 37
+dfs.h: 27
+dfsqrt.c: 5530
+dfsub.c: 15897
+dfu: 4096
+dfu.c: 6025
+dgram.c: 8393
+diag.c: 1739
+diag.h: 1050
+dialog.h: 6696
+dib0070.c: 13441
+dib0070.h: 1691
+dib0700_core.c: 11979
+dib0700_devices.c: 54526
+dib0700.h: 2680
+dib07x0.h: 266
+dib3000.h: 1813
+dib3000mb.c: 23970
+dib3000mb_priv.h: 16232
+dib3000mc.c: 26706
+dib3000mc.h: 2337
+dib7000m.c: 40754
+dib7000m.h: 2102
+dib7000p.c: 40757
+dib7000p.h: 2849
+dibusb-common.c: 12123
+dibusb.h: 3337
+dibusb-mb.c: 14485
+dibusb-mc.c: 5124
+dibx000_common.c: 4156
+dibx000_common.h: 2896
+di.c: 31214
+di_dbg.h: 1102
+diddfunc.c: 2703
+di_defs.h: 8217
+did_vers.h: 933
+diffconfig: 3642
+dig: 4096
+digest.c: 2574
+digi1.h: 3665
+digi_acceleport.c: 58641
+digiepca.txt: 3789
+digiFep1.h: 1928
+digiPCI.h: 1382
+digitv.c: 9329
+digitv.h: 1457
+digsy_mtc.dts: 5933
+di.h: 4386
+dilnetpc.c: 13589
+dino.c: 31503
+dio: 4096
+dio.c: 8573
+dio-driver.c: 3552
+dio.h: 11200
+dio-sysfs.c: 2250
+dir.c: 25683
+direct.c: 6527
+direct.h: 1640
+direct-io.c: 35225
+directory.c: 7736
+directory-locking: 5153
+dirent.h: 177
+dir_f.c: 10085
+dir_f.h: 1267
+dir_fplus.c: 4598
+dir_fplus.h: 1014
+dir.h: 1246
+dirhash.c: 6496
+dir-item.c: 11583
+disable-tsc-ctxt-sw-stress-test.c: 1724
+disable-tsc-on-off-stress-test.c: 1717
+disable-tsc-test.c: 2121
+dis-asm.h: 895
+disassemble.c: 19044
+disassemble.h: 1766
+dis.c: 41703
+discontig.c: 1271
+discover.c: 9895
+discover.h: 2378
+discovery.c: 12785
+discovery.h: 3572
+disk-io.c: 67604
+disk-io.h: 4751
+diskonchip.c: 50636
+disk-shock-protection.txt: 6881
+dispc.c: 37465
+dispc.h: 1183
+display: 4096
+display7seg.c: 6503
+display7seg.h: 1882
+display.c: 1573
+display_gx1.c: 6318
+display_gx1.h: 4598
+display_gx.c: 4945
+display.h: 2117
+display-sysfs.c: 6099
+diu.txt: 470
+div64.c: 3889
+div64-generic.c: 283
+div64.h: 371
+div64.S: 3866
+diva.c: 34488
+divacapi.h: 50994
+diva_didd.c: 3571
+diva_dma.c: 2843
+diva_dma.h: 1993
+diva.h: 1010
+divamnt.c: 5616
+diva_pci.h: 631
+divasfunc.c: 5512
+divasi.c: 12379
+divasmain.c: 21787
+divasproc.c: 10764
+divasync.h: 20126
+divdi3.S: 6280
+divert: 4096
+divert_init.c: 2399
+divert_procfs.c: 8581
+divide.S: 4293
+divsi3.S: 6392
+div_small.S: 1546
+div_Xsig.S: 10096
+dl2k.c: 48901
+dl2k.h: 14949
+dl2k.txt: 9387
+dlci.c: 11723
+DLINK.txt: 7386
+dlm: 4096
+dlmapi.h: 9492
+dlmast.c: 13019
+dlmcommon.h: 29686
+dlmconstants.h: 5013
+dlmconvert.c: 15590
+dlmconvert.h: 1218
+dlmdebug.c: 28761
+dlmdebug.h: 2109
+dlm_device.h: 2536
+dlmdomain.c: 49292
+dlmdomain.h: 1165
+dlmfs.c: 15242
+dlmfs.txt: 4319
+dlmfsver.c: 1211
+dlmfsver.h: 997
+dlmglue.c: 110475
+dlmglue.h: 5587
+dlm.h: 5602
+dlm_internal.h: 16633
+dlmlock.c: 19997
+dlmmaster.c: 96511
+dlm_netlink.h: 1064
+dlm_plock.h: 1135
+dlmrecovery.c: 85132
+dlmthread.c: 21013
+dlmunlock.c: 19250
+dlmver.c: 1203
+dlmver.h: 991
+dm1105: 4096
+dm1105.c: 22399
+dm355.c: 17263
+dm355evm_keys.c: 8928
+dm355evm_msp.c: 10717
+dm355evm_msp.h: 2879
+dm355.h: 586
+dm644x.c: 14946
+dm644x.h: 1316
+dm646x.c: 15438
+dm646x.h: 757
+dm9000.c: 34291
+dm9000.h: 4167
+dm9000.txt: 5137
+dm9601.c: 15941
+dma: 4096
+dma-alloc.c: 4571
+dma-api.c: 9315
+DMA-API.txt: 28886
+DMA-attributes.txt: 1376
+dma-attrs.h: 1758
+dmabounce.c: 14340
+dmabrg.c: 5279
+dmabrg.h: 497
+dmabuf.c: 35686
+dma.c: 6328
+dmac.c: 4805
+dmac.h: 11517
+dma-coherence.h: 1492
+dma-coherent.c: 3667
+dma-coherent.h: 891
+dmacopy.c: 909
+dma-core.h: 639
+dmactl-regs.h: 4663
+dma-debug.c: 31988
+dma-debug.h: 4915
+dma-default.c: 8575
+dma_defs_asm.h: 14594
+dma_defs.h: 14110
+dmaengine.c: 28040
+dmaengine.h: 15831
+dmaengine.txt: 42
+dma-g2.c: 4776
+dma.h: 2547
+dma-iommu.c: 3128
+dma-isa.c: 5163
+DMA-ISA-LPC.txt: 5333
+dma_lib.c: 16254
+dma-m2p.c: 9922
+dma-mapping-broken.h: 2488
+dma-mapping.c: 5434
+dma-mapping-common.h: 5646
+dma-mapping.h: 4368
+DMA-mapping.txt: 27929
+dma_mm.h: 455
+dma-mx1-mx2.c: 23615
+dma-mx1-mx2.h: 2711
+dma_no.h: 16955
+dma-noncoherent.c: 10156
+dma-octeon.c: 10532
+dma-plat.h: 2025
+dmapool.c: 13226
+dmapool.h: 923
+dma-pvr2.c: 2423
+dmar.c: 31385
+dma_remapping.h: 988
+dmar.h: 6143
+dmascc.c: 37724
+dma-sh4a.h: 2469
+dma-sh7760.c: 10216
+dma-sh.c: 7913
+dma-sh.h: 2862
+dmasound: 4096
+dmasound_atari.c: 42606
+dmasound_core.c: 44456
+dmasound.h: 8131
+dmasound_paula.c: 19160
+dmasound_q40.c: 14354
+dma-swiotlb.c: 4748
+dma-sysfs.c: 4348
+dmatest.c: 15129
+dma_timer.c: 2282
+dma.txt: 6352
+DMA.txt: 6352
+dma_v.h: 1177
+dm-bio-record.h: 1629
+dm.c: 60780
+dm-crypt.c: 32243
+dm-crypt.txt: 1485
+dm-delay.c: 8567
+dm-dirty-log.h: 3944
+dme1737: 11748
+dme1737.c: 74868
+dmesg.c: 1657
+dm-exception-store.c: 6745
+dm-exception-store.h: 4659
+dmfe.c: 60351
+dmfe.txt: 2168
+dm.h: 3933
+dmi.h: 411
+dmi-id.c: 6586
+dm-io.c: 11366
+dm-ioctl.c: 33212
+dm-ioctl.h: 9109
+dm-io.h: 2051
+dm-io.txt: 3298
+dmi_scan.c: 15130
+dm-kcopyd.c: 14244
+dm-kcopyd.h: 1335
+dm-linear.c: 3614
+dm-log.c: 19367
+dm-log.txt: 2397
+dm-log-userspace-base.c: 16497
+dm-log-userspace.h: 12944
+dm-log-userspace-transfer.c: 6936
+dm-log-userspace-transfer.h: 452
+dmm32at.c: 30666
+dm-mpath.c: 37626
+dm-mpath.h: 415
+dm-path-selector.c: 2473
+dm-path-selector.h: 2533
+dm-queue-length.c: 5495
+dm-queue-length.txt: 1218
+dm-raid1.c: 32159
+dm-region-hash.c: 18043
+dm-region-hash.h: 3217
+dm-round-robin.c: 4673
+dm-service-time.c: 8360
+dm-service-time.txt: 3243
+dm-snap.c: 33940
+dm-snap-persistent.c: 17550
+dm-snap-transient.c: 3687
+dm-stripe.c: 8013
+dm-sysfs.c: 2204
+dm-table.c: 27836
+dm-target.c: 2600
+dmtimer.c: 22824
+dmtimer.h: 3450
+dm-uevent.c: 5482
+dm-uevent.h: 1678
+dm-uevent.txt: 2650
+dmv182.c: 3833
+dmx3191d.c: 4547
+dmxdev.c: 28366
+dmxdev.h: 2409
+dmx.h: 3848
+dm-zero.c: 1495
+dn_dev.c: 33824
+dn_dev.h: 5493
+dnet.c: 25715
+dnet.h: 7221
+dnfb.c: 8139
+dn_fib.c: 18396
+dn_fib.h: 4894
+dn.h: 4527
+dn_ints.c: 1049
+dn_neigh.c: 15875
+dn_neigh.h: 824
+dn_nsp.h: 6229
+dn_nsp_in.c: 21566
+dn_nsp_out.c: 17942
+dnode.c: 30235
+dnotify: 4096
+dnotify.c: 12385
+dnotify.h: 978
+dnotify.txt: 3565
+dn_route.c: 44768
+dn_route.h: 4165
+dn_rtmsg.c: 3778
+dn_rules.c: 5755
+dns323-setup.c: 10831
+dns_resolve.c: 3678
+dns_resolve.h: 1294
+dn_table.c: 20482
+dn_timer.c: 3167
+do_balan.c: 58466
+doc2000.c: 32664
+doc2000.h: 5486
+doc2001.c: 25107
+doc2001plus.c: 31825
+DocBook: 4096
+docecc.c: 15968
+dock.c: 31358
+docprobe.c: 10340
+docproc.c: 11716
+do_csum.S: 2991
+Documentation: 4096
+do_func.S: 13813
+domain.c: 29471
+domain.h: 2107
+do_mounts.c: 9465
+do_mounts.h: 1396
+do_mounts_initrd.c: 3256
+do_mounts_md.c: 8071
+do_mounts_rd.c: 8166
+donauboe.c: 48207
+donauboe.h: 14213
+dontdiff: 1964
+doorbell.c: 2900
+doorbell.h: 2894
+dot11d.c: 5434
+dot11d.h: 2916
+dot_command.c: 4062
+dot_command.h: 2259
+dot.gdbinit: 5372
+dot.gdbinit_200MHz_16MB: 5763
+dot.gdbinit_300MHz_32MB: 5763
+dot.gdbinit_400MHz_32MB: 5764
+dot.gdbinit.nommu: 3891
+dot.gdbinit.smp: 8938
+dot.gdbinit.vdec2: 5442
+do_timer.h: 349
+double_cpdo.c: 4122
+doublefault_32.c: 1732
+double.h: 6303
+down2.H16: 33610
+down3.bin.ihex: 35892
+down.H16: 36678
+dp_add.c: 4700
+dpc.c: 58689
+dpc.h: 1771
+dp_cmp.c: 1842
+dpcsup.c: 9553
+dp_div.c: 4369
+dp_fint.c: 1932
+dp_flong.c: 1912
+dp_frexp.c: 1450
+dp_fsp.c: 1879
+dp_logb.c: 1446
+dpmc.c: 3024
+dpmc.h: 1247
+dpmc_modes.S: 14539
+dp_modf.c: 2064
+dp_mul.c: 4812
+dp_scalb.c: 1508
+dp_simple.c: 2057
+dp_sqrt.c: 4372
+dp_sub.c: 4977
+dpt: 4096
+dpt_i2o.c: 96500
+dpti.h: 11787
+dpti_i2o.h: 13449
+dpti_ioctl.h: 5365
+dp_tint.c: 3021
+dpti.txt: 3614
+dp_tlong.c: 3061
+dptsig.h: 14986
+dqblk_qtree.h: 2108
+dqblk_v1.h: 342
+dqblk_v2.h: 367
+dqblk_xfs.h: 6607
+dqueue.c: 2180
+dqueue.h: 1007
+dquot.c: 72530
+draft-ietf-cipso-ipsecurity-01.txt: 28638
+dram_init.S: 3913
+draw_functrace.py: 3560
+dreamcast_defconfig: 25856
+driver: 11995
+driver.c: 54722
+driver-changes.txt: 4022
+driver_chipcommon.c: 13262
+driver_chipcommon_pmu.c: 17510
+driver_extif.c: 3829
+driver_gige.c: 7415
+driver.h: 4405
+driver_mipscore.c: 6999
+driver-model: 4096
+driver-model.txt: 10127
+driver-ops.h: 5035
+driver_pcicore.c: 16619
+drivers: 4096
+drivers.c: 22567
+drivers-testing.txt: 2173
+driver.txt: 8049
+drm: 4096
+drm_agpsupport.c: 13149
+drm_auth.c: 5698
+drm_bufs.c: 44350
+drm_cache.c: 2119
+drm_context.c: 11821
+drm_core.h: 1468
+drm_crtc.c: 63999
+drm_crtc.h: 25347
+drm_crtc_helper.c: 29207
+drm_crtc_helper.h: 4951
+drm_debugfs.c: 6275
+drm_dma.c: 4147
+drm_drawable.c: 5166
+drm_drv.c: 16709
+drm_edid.c: 24730
+drm_edid.h: 5722
+drm_fops.c: 14460
+drm_gem.c: 14905
+drm.h: 23018
+drm_hashtab.c: 5440
+drm_hashtab.h: 2589
+drm_info.c: 9606
+drm_ioc32.c: 33632
+drm_ioctl.c: 9402
+drm_irq.c: 17068
+drm_lock.c: 11107
+drm_memory.c: 5012
+drm_memory.h: 1936
+drm_mm.c: 9213
+drm_mm.h: 3301
+drm_mode.h: 6855
+drm_modes.c: 14802
+drm_os_linux.h: 4047
+drm_pci.c: 3839
+drm_pciids.h: 40171
+drmP.h: 49714
+drm_proc.c: 6339
+drm_sarea.h: 2655
+drm_scatter.c: 5431
+drm_sman.c: 8782
+drm_sman.h: 5975
+drm_stub.c: 13017
+drm_sysfs.c: 13561
+drm_vm.c: 18670
+drop_caches.c: 1684
+drop_monitor.c: 8677
+drp-avail.c: 8822
+drp.c: 24684
+drp-ie.c: 9743
+drv.c: 22503
+drvfbi.c: 12647
+drx397xD.c: 30335
+drx397xD_fw.h: 1525
+drx397xD.h: 3015
+ds1286.h: 1223
+ds1287.h: 1019
+ds1302.c: 7604
+ds1305.h: 1068
+ds1603.c: 3162
+ds1603.h: 566
+ds1620.c: 8486
+ds1621: 2670
+ds1621.c: 9932
+ds1682.c: 7160
+ds17287rtc.h: 2676
+ds1_ctrl.fw.ihex: 33804
+ds1_dsp.fw.ihex: 364
+ds1e_ctrl.fw.ihex: 33804
+ds1wm.c: 11691
+ds1wm.h: 114
+ds2482: 743
+ds2482.c: 14041
+ds2490: 3576
+ds2490.c: 24260
+ds2760_battery.c: 13485
+dsa: 4096
+dsa.c: 9418
+dsa.h: 1617
+dsa_priv.h: 4060
+dsbr100.c: 17605
+ds.c: 38706
+dsc.c: 1195
+dscc4.c: 55052
+dsdt-override.txt: 247
+dsemul.c: 4501
+dsfield.c: 19154
+dsfield.h: 1127
+ds.h: 8003
+dsinit.c: 6745
+dsmethod.c: 19169
+dsmg600.h: 1216
+dsmg600-pci.c: 1898
+dsmg600-setup.c: 7030
+dsmthdat.c: 21585
+dsobject.c: 23900
+dsopcode.c: 39305
+dsp56k: 4096
+dsp56k.c: 12404
+dsp56k.h: 1269
+dsp_audio.c: 11056
+dsp_biquad.h: 1622
+dsp_blowfish.c: 23738
+dspbootcode.bin.ihex: 36048
+dsp_cmx.c: 52826
+dsp_common.h: 1309
+dsp_core.c: 33551
+dsp_defs.h: 12149
+dspdids.h: 2695
+dsp_dtmf.c: 7570
+dsp_ecdis.h: 3527
+dsp.h: 7893
+dsp_hwec.c: 3049
+dsp_hwec.h: 242
+dsp_pipeline.c: 8348
+dsp_spos.c: 55617
+dsp_spos.h: 7631
+dsp_spos_scb_lib.c: 49424
+dsp_tones.c: 17264
+dsp_tst.h: 1486
+dsrv4bri.h: 1644
+dsrv_bri.h: 1178
+dsrv_pri.h: 1247
+ds_selftest.c: 9393
+ds_selftest.h: 363
+dst: 4096
+dst.c: 49967
+dst_ca.c: 21634
+dst_ca.h: 1591
+dst_common.h: 4277
+dst.h: 14556
+dst_priv.h: 598
+dstr.c: 5143
+dsutils.c: 25450
+dswexec.c: 19731
+dswload.c: 31066
+dswscope.c: 6750
+dswstate.c: 21428
+dt019x.c: 9062
+dt2801.c: 15251
+dt2811.c: 14680
+dt2814.c: 8589
+dt2815.c: 7337
+dt2817.c: 4517
+dt282x.c: 35248
+dt3000.c: 23494
+dt9812.c: 28480
+dtc: 4096
+dt.c: 16907
+dtc2278.c: 3867
+dtc3x80.txt: 1952
+dtc.c: 13348
+dtc.h: 2644
+dtc-lexer.l: 6979
+dtc-lexer.lex.c_shipped: 57920
+dtc-parser.tab.c_shipped: 55472
+dtc-parser.tab.h_shipped: 3233
+dtc-parser.y: 6540
+dtc-src: 4096
+dtl1_cs.c: 14325
+dtlb_miss.S: 747
+dtlb_prot.S: 1267
+dtl.c: 6493
+dtlk.c: 16644
+dtlk.h: 3768
+dts: 4096
+dts-bindings: 4096
+dtt200u.c: 9848
+dtt200u-fe.c: 5300
+dtt200u.h: 1606
+dtv5100.c: 5845
+dtv5100.h: 1534
+dum.h: 7581
+dummy.c: 3850
+dummycon.c: 1805
+dummy_hcd.c: 50629
+dump_pagetables.c: 8879
+dumprequest.c: 3343
+dumprequest.h: 2117
+dumpstack_32.c: 3323
+dumpstack_64.c: 7276
+dump_stack.c: 290
+dumpstack.c: 8067
+dumpstack.h: 1003
+dump_tlb.c: 2643
+dv1394: 390
+dv1394.c: 74226
+dv1394.h: 10409
+dv1394-private.h: 17471
+dvb: 4096
+dvb-bt8xx.c: 28096
+dvb-bt8xx.h: 1816
+dvb_ca_en50221.c: 45737
+dvb_ca_en50221.h: 4082
+dvb-core: 4096
+dvb_demux.c: 30507
+dvb_demux.h: 3579
+dvbdev.c: 11761
+dvbdev.h: 4065
+dvb_dummy_fe.c: 7049
+dvb_dummy_fe.h: 1698
+dvb_filter.c: 12922
+dvb_filter.h: 6064
+dvb_frontend.c: 54720
+dvb_frontend.h: 11618
+dvb_math.c: 5423
+dvb_math.h: 1974
+dvb_net.c: 42892
+dvb_net.h: 1379
+dvb-pll.c: 17175
+dvb-pll.h: 1617
+dvb_ringbuffer.c: 7188
+dvb_ringbuffer.h: 6340
+dvb-ttusb-budget.c: 44105
+dvb-usb: 12288
+dvb-usb-common.h: 2150
+dvb-usb-dvb.c: 5850
+dvb-usb-firmware.c: 3956
+dvb-usb.h: 12194
+dvb-usb-i2c.c: 1061
+dvb-usb-ids.h: 11042
+dvb-usb-init.c: 8477
+dvb-usb-remote.c: 5519
+dvb-usb-urb.c: 2585
+dvi.c: 18260
+dvi.h: 2461
+dvma.c: 1265
+dvma.h: 9864
+dvo_ch7017.c: 14698
+dvo_ch7xxx.c: 9179
+dvo.h: 4860
+dvo_ivch.c: 10628
+dvo_sil164.c: 7534
+dvo_tfp410.c: 8848
+dw2102.c: 27129
+dw2102.h: 240
+dwarf2.h: 2393
+dw_dmac.c: 37849
+dw_dmac.h: 3078
+dw_dmac_regs.h: 6137
+dynamic_debug.c: 18386
+dynamic_debug.h: 2666
+dynamic-debug-howto.txt: 8633
+dyn.lds.S: 5092
+dz.c: 23133
+dz.h: 5439
+e00154b8e949bf4b89ac198aef9a247532ac2d: 297
+e100: 4096
+e1000: 4096
+e1000_82575.c: 42179
+e1000_82575.h: 8176
+e1000_defines.h: 28796
+e1000e: 4096
+e1000_ethtool.c: 56605
diff --git a/tests/drive_del-test.c b/tests/drive_del-test.c
index 4a1a0889c8..2f9474e03c 100644
--- a/tests/drive_del-test.c
+++ b/tests/drive_del-test.c
@@ -63,6 +63,24 @@ static void test_drive_without_dev(void)
qtest_end();
}
+/*
+ * qvirtio_get_dev_type:
+ * Returns: the preferred virtio bus/device type for the current architecture.
+ * TODO: delete this
+ */
+static const char *qvirtio_get_dev_type(void)
+{
+ const char *arch = qtest_get_arch();
+
+ if (g_str_equal(arch, "arm") || g_str_equal(arch, "aarch64")) {
+ return "device"; /* for virtio-mmio */
+ } else if (g_str_equal(arch, "s390x")) {
+ return "ccw";
+ } else {
+ return "pci";
+ }
+}
+
static void test_after_failed_device_add(void)
{
char driver[32];
@@ -119,16 +137,11 @@ static void test_drive_del_device_del(void)
int main(int argc, char **argv)
{
- const char *arch = qtest_get_arch();
-
g_test_init(&argc, &argv, NULL);
qtest_add_func("/drive_del/without-dev", test_drive_without_dev);
- /* TODO I guess any arch with a hot-pluggable virtio bus would do */
- if (!strcmp(arch, "i386") || !strcmp(arch, "x86_64") ||
- !strcmp(arch, "ppc") || !strcmp(arch, "ppc64") ||
- !strcmp(arch, "s390x")) {
+ if (qvirtio_get_dev_type() != NULL) {
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/e1000-test.c b/tests/e1000-test.c
index 0c5fcdcc44..9e67916169 100644
--- a/tests/e1000-test.c
+++ b/tests/e1000-test.c
@@ -9,22 +9,15 @@
#include "qemu/osdep.h"
#include "libqtest.h"
+#include "libqos/qgraph.h"
+#include "libqos/pci.h"
-/* Tests only initialization so far. TODO: Replace with functional tests */
-static void test_device(gconstpointer data)
-{
- const char *model = data;
- QTestState *s;
- char *args;
-
- args = g_strdup_printf("-device %s", model);
- s = qtest_start(args);
+typedef struct QE1000 QE1000;
- if (s) {
- qtest_quit(s);
- }
- g_free(args);
-}
+struct QE1000 {
+ QOSGraphObject obj;
+ QPCIDevice dev;
+};
static const char *models[] = {
"e1000",
@@ -33,19 +26,42 @@ static const char *models[] = {
"e1000-82545em",
};
-int main(int argc, char **argv)
+static void *e1000_get_driver(void *obj, const char *interface)
{
- int i;
+ QE1000 *e1000 = obj;
- g_test_init(&argc, &argv, NULL);
+ if (!g_strcmp0(interface, "pci-device")) {
+ return &e1000->dev;
+ }
- for (i = 0; i < ARRAY_SIZE(models); i++) {
- char *path;
+ fprintf(stderr, "%s not present in e1000e\n", interface);
+ g_assert_not_reached();
+}
- path = g_strdup_printf("e1000/%s", models[i]);
- qtest_add_data_func(path, models[i], test_device);
- g_free(path);
- }
+static void *e1000_create(void *pci_bus, QGuestAllocator *alloc, void *addr)
+{
+ QE1000 *e1000 = g_new0(QE1000, 1);
+ QPCIBus *bus = pci_bus;
+
+ qpci_device_init(&e1000->dev, bus, addr);
+ e1000->obj.get_driver = e1000_get_driver;
+
+ return &e1000->obj;
+}
+
+static void e1000_register_nodes(void)
+{
+ int i;
+ QOSGraphEdgeOptions opts = {
+ .extra_device_opts = "addr=04.0",
+ };
+ add_qpci_address(&opts, &(QPCIAddress) { .devfn = QPCI_DEVFN(4, 0) });
- return g_test_run();
+ for (i = 0; i < ARRAY_SIZE(models); i++) {
+ qos_node_create_driver(models[i], e1000_create);
+ qos_node_consumes(models[i], "pci-bus", &opts);
+ qos_node_produces(models[i], "pci-device");
+ }
}
+
+libqos_init(e1000_register_nodes);
diff --git a/tests/e1000e-test.c b/tests/e1000e-test.c
index c9408a5d1f..77ba8095bb 100644
--- a/tests/e1000e-test.c
+++ b/tests/e1000e-test.c
@@ -32,210 +32,9 @@
#include "qemu/iov.h"
#include "qemu/bitops.h"
#include "libqos/malloc.h"
-#include "libqos/malloc-pc.h"
-#include "libqos/malloc-generic.h"
+#include "libqos/e1000e.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;
- QPCIBar 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 **res = data;
-
- g_assert_null(*res);
- *res = 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);
-
- /* 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)
+static void e1000e_send_verify(QE1000E *d, int *test_sockets, QGuestAllocator *alloc)
{
struct {
uint64_t buffer_addr;
@@ -268,7 +67,7 @@ static void e1000e_send_verify(e1000e_device *d)
uint32_t recv_len;
/* Prepare test data buffer */
- uint64_t data = guest_alloc(test_alloc, data_len);
+ uint64_t data = guest_alloc(alloc, data_len);
memwrite(data, "TEST", 5);
/* Prepare TX descriptor */
@@ -296,10 +95,10 @@ static void e1000e_send_verify(e1000e_device *d)
g_assert_cmpstr(buffer, == , "TEST");
/* Free test data buffer */
- guest_free(test_alloc, data);
+ guest_free(alloc, data);
}
-static void e1000e_receive_verify(e1000e_device *d)
+static void e1000e_receive_verify(QE1000E *d, int *test_sockets, QGuestAllocator *alloc)
{
union {
struct {
@@ -348,7 +147,7 @@ static void e1000e_receive_verify(e1000e_device *d)
g_assert_cmpint(ret, == , sizeof(test) + sizeof(len));
/* Prepare test data buffer */
- uint64_t data = guest_alloc(test_alloc, data_len);
+ uint64_t data = guest_alloc(alloc, data_len);
/* Prepare RX descriptor */
memset(&descr, 0, sizeof(descr));
@@ -369,111 +168,108 @@ static void e1000e_receive_verify(e1000e_device *d)
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_alloc = pc_alloc_init(global_qtest);
- g_assert_nonnull(test_alloc);
-
- test_bus = qpci_init_pc(global_qtest, test_alloc);
- g_assert_nonnull(test_bus);
-
- e1000e_device_init(test_bus, d);
+ guest_free(alloc, data);
}
-static void data_test_clear(e1000e_device *d)
+static void test_e1000e_init(void *obj, void *data, QGuestAllocator * alloc)
{
- e1000e_device_clear(test_bus, d);
- close(test_sockets[0]);
- pc_alloc_uninit(test_alloc);
- g_free(d->pci_dev);
- qpci_free_pc(test_bus);
- qtest_end();
+ /* init does nothing */
}
-static void test_e1000e_init(gconstpointer data)
+static void test_e1000e_tx(void *obj, void *data, QGuestAllocator * alloc)
{
- e1000e_device d;
-
- data_test_init(&d);
- data_test_clear(&d);
-}
-
-static void test_e1000e_tx(gconstpointer data)
-{
- e1000e_device d;
+ QE1000E_PCI *e1000e = obj;
+ QE1000E *d = &e1000e->e1000e;
+ QOSGraphObject *e_object = obj;
+ QPCIDevice *dev = e_object->get_driver(e_object, "pci-device");
+
+ /* FIXME: add spapr support */
+ if (qpci_check_buggy_msi(dev)) {
+ return;
+ }
- data_test_init(&d);
- e1000e_send_verify(&d);
- data_test_clear(&d);
+ e1000e_send_verify(d, data, alloc);
}
-static void test_e1000e_rx(gconstpointer data)
+static void test_e1000e_rx(void *obj, void *data, QGuestAllocator * alloc)
{
- e1000e_device d;
+ QE1000E_PCI *e1000e = obj;
+ QE1000E *d = &e1000e->e1000e;
+ QOSGraphObject *e_object = obj;
+ QPCIDevice *dev = e_object->get_driver(e_object, "pci-device");
+
+ /* FIXME: add spapr support */
+ if (qpci_check_buggy_msi(dev)) {
+ return;
+ }
- data_test_init(&d);
- e1000e_receive_verify(&d);
- data_test_clear(&d);
+ e1000e_receive_verify(d, data, alloc);
}
-static void test_e1000e_multiple_transfers(gconstpointer data)
+static void test_e1000e_multiple_transfers(void *obj, void *data,
+ QGuestAllocator *alloc)
{
static const long iterations = 4 * 1024;
long i;
- e1000e_device d;
+ QE1000E_PCI *e1000e = obj;
+ QE1000E *d = &e1000e->e1000e;
+ QOSGraphObject *e_object = obj;
+ QPCIDevice *dev = e_object->get_driver(e_object, "pci-device");
- data_test_init(&d);
+ /* FIXME: add spapr support */
+ if (qpci_check_buggy_msi(dev)) {
+ return;
+ }
for (i = 0; i < iterations; i++) {
- e1000e_send_verify(&d);
- e1000e_receive_verify(&d);
+ e1000e_send_verify(d, data, alloc);
+ e1000e_receive_verify(d, data, alloc);
}
- data_test_clear(&d);
}
-static void test_e1000e_hotplug(gconstpointer data)
+static void test_e1000e_hotplug(void *obj, void *data, QGuestAllocator * alloc)
{
- qtest_start("-device e1000e");
-
qtest_qmp_device_add("e1000e", "e1000e_net", "{'addr': '0x06'}");
qpci_unplug_acpi_device_test("e1000e_net", 0x06);
+}
+
+static void data_test_clear(void *sockets)
+{
+ int *test_sockets = sockets;
- qtest_end();
+ close(test_sockets[0]);
+ qos_invalidate_command_line();
+ close(test_sockets[1]);
+ g_free(test_sockets);
}
-int main(int argc, char **argv)
+static void *data_test_init(GString *cmd_line, void *arg)
{
- g_test_init(&argc, &argv, NULL);
+ int *test_sockets = g_new(int, 2);
+ int ret = socketpair(PF_UNIX, SOCK_STREAM, 0, test_sockets);
+ g_assert_cmpint(ret, != , -1);
- 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);
+ g_string_append_printf(cmd_line, " -netdev socket,fd=%d,id=hs0 ",
+ test_sockets[1]);
- return g_test_run();
+ g_test_queue_destroy(data_test_clear, test_sockets);
+ return test_sockets;
}
+
+static void register_e1000e_test(void)
+{
+ QOSGraphTestOptions opts = {
+ .before = data_test_init,
+ };
+
+ qos_add_test("init", "e1000e", test_e1000e_init, &opts);
+ qos_add_test("tx", "e1000e", test_e1000e_tx, &opts);
+ qos_add_test("rx", "e1000e", test_e1000e_rx, &opts);
+ qos_add_test("multiple_transfers", "e1000e",
+ test_e1000e_multiple_transfers, &opts);
+ qos_add_test("hotplug", "e1000e", test_e1000e_hotplug, &opts);
+}
+
+libqos_init(register_e1000e_test);
diff --git a/tests/eepro100-test.c b/tests/eepro100-test.c
index bdc8a67d57..90b5c1afd9 100644
--- a/tests/eepro100-test.c
+++ b/tests/eepro100-test.c
@@ -9,23 +9,15 @@
#include "qemu/osdep.h"
#include "libqtest.h"
+#include "libqos/qgraph.h"
+#include "libqos/pci.h"
-static void test_device(gconstpointer data)
-{
- const char *model = data;
- QTestState *s;
- char *args;
-
- args = g_strdup_printf("-device %s", model);
- s = qtest_start(args);
-
- /* Tests only initialization so far. TODO: Implement functional tests */
+typedef struct QEEPRO100 QEEPRO100;
- if (s) {
- qtest_quit(s);
- }
- g_free(args);
-}
+struct QEEPRO100 {
+ QOSGraphObject obj;
+ QPCIDevice dev;
+};
static const char *models[] = {
"i82550",
@@ -43,19 +35,42 @@ static const char *models[] = {
"i82801",
};
-int main(int argc, char **argv)
+static void *eepro100_get_driver(void *obj, const char *interface)
{
- int i;
+ QEEPRO100 *eepro100 = obj;
- g_test_init(&argc, &argv, NULL);
+ if (!g_strcmp0(interface, "pci-device")) {
+ return &eepro100->dev;
+ }
- for (i = 0; i < ARRAY_SIZE(models); i++) {
- char *path;
+ fprintf(stderr, "%s not present in eepro100\n", interface);
+ g_assert_not_reached();
+}
- path = g_strdup_printf("eepro100/%s", models[i]);
- qtest_add_data_func(path, models[i], test_device);
- g_free(path);
- }
+static void *eepro100_create(void *pci_bus, QGuestAllocator *alloc, void *addr)
+{
+ QEEPRO100 *eepro100 = g_new0(QEEPRO100, 1);
+ QPCIBus *bus = pci_bus;
+
+ qpci_device_init(&eepro100->dev, bus, addr);
+ eepro100->obj.get_driver = eepro100_get_driver;
+
+ return &eepro100->obj;
+}
+
+static void eepro100_register_nodes(void)
+{
+ int i;
+ QOSGraphEdgeOptions opts = {
+ .extra_device_opts = "addr=04.0",
+ };
- return g_test_run();
+ add_qpci_address(&opts, &(QPCIAddress) { .devfn = QPCI_DEVFN(4, 0) });
+ for (i = 0; i < ARRAY_SIZE(models); i++) {
+ qos_node_create_driver(models[i], eepro100_create);
+ qos_node_consumes(models[i], "pci-bus", &opts);
+ qos_node_produces(models[i], "pci-device");
+ }
}
+
+libqos_init(eepro100_register_nodes);
diff --git a/tests/es1370-test.c b/tests/es1370-test.c
index 199fe193ce..d845cd06f8 100644
--- a/tests/es1370-test.c
+++ b/tests/es1370-test.c
@@ -9,23 +9,49 @@
#include "qemu/osdep.h"
#include "libqtest.h"
+#include "libqos/qgraph.h"
+#include "libqos/pci.h"
-/* Tests only initialization so far. TODO: Replace with functional tests */
-static void nop(void)
+typedef struct QES1370 QES1370;
+
+struct QES1370 {
+ QOSGraphObject obj;
+ QPCIDevice dev;
+};
+
+static void *es1370_get_driver(void *obj, const char *interface)
{
+ QES1370 *es1370 = obj;
+
+ if (!g_strcmp0(interface, "pci-device")) {
+ return &es1370->dev;
+ }
+
+ fprintf(stderr, "%s not present in e1000e\n", interface);
+ g_assert_not_reached();
}
-int main(int argc, char **argv)
+static void *es1370_create(void *pci_bus, QGuestAllocator *alloc, void *addr)
{
- int ret;
+ QES1370 *es1370 = g_new0(QES1370, 1);
+ QPCIBus *bus = pci_bus;
- g_test_init(&argc, &argv, NULL);
- qtest_add_func("/es1370/nop", nop);
+ qpci_device_init(&es1370->dev, bus, addr);
+ es1370->obj.get_driver = es1370_get_driver;
- qtest_start("-device ES1370");
- ret = g_test_run();
+ return &es1370->obj;
+}
- qtest_end();
+static void es1370_register_nodes(void)
+{
+ QOSGraphEdgeOptions opts = {
+ .extra_device_opts = "addr=04.0",
+ };
+ add_qpci_address(&opts, &(QPCIAddress) { .devfn = QPCI_DEVFN(4, 0) });
- return ret;
+ qos_node_create_driver("ES1370", es1370_create);
+ qos_node_consumes("ES1370", "pci-bus", &opts);
+ qos_node_produces("ES1370", "pci-device");
}
+
+libqos_init(es1370_register_nodes);
diff --git a/tests/i440fx-test.c b/tests/i440fx-test.c
index 4390e5591e..69205b58a8 100644
--- a/tests/i440fx-test.c
+++ b/tests/i440fx-test.c
@@ -38,7 +38,7 @@ static QPCIBus *test_start_get_bus(const TestData *s)
cmdline = g_strdup_printf("-smp %d", s->num_cpus);
qtest_start(cmdline);
g_free(cmdline);
- return qpci_init_pc(global_qtest, NULL);
+ return qpci_new_pc(global_qtest, NULL);
}
static void test_i440fx_defaults(gconstpointer opaque)
diff --git a/tests/ide-test.c b/tests/ide-test.c
index 300d64e77d..d863a99f7f 100644
--- a/tests/ide-test.c
+++ b/tests/ide-test.c
@@ -120,7 +120,7 @@ enum {
#define assert_bit_clear(data, mask) g_assert_cmphex((data) & (mask), ==, 0)
static QPCIBus *pcibus = NULL;
-static QGuestAllocator *guest_malloc;
+static QGuestAllocator guest_malloc;
static char tmp_path[] = "/tmp/qtest.XXXXXX";
static char debug_path[] = "/tmp/qtest-blkdebug.XXXXXX";
@@ -135,7 +135,7 @@ static void ide_test_start(const char *cmdline_fmt, ...)
va_end(ap);
qtest_start(cmdline);
- guest_malloc = pc_alloc_init(global_qtest);
+ pc_alloc_init(&guest_malloc, global_qtest, 0);
g_free(cmdline);
}
@@ -146,8 +146,7 @@ static void ide_test_quit(void)
qpci_free_pc(pcibus);
pcibus = NULL;
}
- pc_alloc_uninit(guest_malloc);
- guest_malloc = NULL;
+ alloc_destroy(&guest_malloc);
qtest_end();
}
@@ -157,7 +156,7 @@ static QPCIDevice *get_pci_device(QPCIBar *bmdma_bar, QPCIBar *ide_bar)
uint16_t vendor_id, device_id;
if (!pcibus) {
- pcibus = qpci_init_pc(global_qtest, NULL);
+ pcibus = qpci_new_pc(global_qtest, NULL);
}
/* Find PCI device and verify it's the right one */
@@ -246,7 +245,7 @@ static int send_dma_request(int cmd, uint64_t sector, int nb_sectors,
/* Setup PRDT */
len = sizeof(*prdt) * prdt_entries;
- guest_prdt = guest_alloc(guest_malloc, len);
+ guest_prdt = guest_alloc(&guest_malloc, len);
memwrite(guest_prdt, prdt, len);
qpci_io_writel(dev, bmdma_bar, bmreg_prdt, guest_prdt);
@@ -311,7 +310,7 @@ static void test_bmdma_simple_rw(void)
uint8_t *buf;
uint8_t *cmpbuf;
size_t len = 512;
- uintptr_t guest_buf = guest_alloc(guest_malloc, len);
+ uintptr_t guest_buf = guest_alloc(&guest_malloc, len);
PrdtEntry prdt[] = {
{
@@ -381,7 +380,7 @@ static void test_bmdma_trim(void)
const uint64_t bad_range = trim_range_le(TEST_IMAGE_SIZE / 512 - 1, 2);
size_t len = 512;
uint8_t *buf;
- uintptr_t guest_buf = guest_alloc(guest_malloc, len);
+ uintptr_t guest_buf = guest_alloc(&guest_malloc, len);
PrdtEntry prdt[] = {
{
@@ -625,7 +624,7 @@ static void make_dirty(uint8_t device)
dev = get_pci_device(&bmdma_bar, &ide_bar);
- guest_buf = guest_alloc(guest_malloc, len);
+ guest_buf = guest_alloc(&guest_malloc, len);
buf = g_malloc(len);
memset(buf, rand() % 255 + 1, len);
g_assert(guest_buf);
@@ -986,7 +985,7 @@ static void test_cdrom_dma(void)
"-device ide-cd,drive=sr0,bus=ide.0", tmp_path);
qtest_irq_intercept_in(global_qtest, "ioapic");
- guest_buf = guest_alloc(guest_malloc, len);
+ guest_buf = guest_alloc(&guest_malloc, len);
prdt[0].addr = cpu_to_le32(guest_buf);
prdt[0].size = cpu_to_le32(len | PRDT_EOT);
diff --git a/tests/ipoctal232-test.c b/tests/ipoctal232-test.c
index 684914164d..42d53718b8 100644
--- a/tests/ipoctal232-test.c
+++ b/tests/ipoctal232-test.c
@@ -9,23 +9,40 @@
#include "qemu/osdep.h"
#include "libqtest.h"
+#include "libqos/qgraph.h"
+
+typedef struct QIpoctal232 QIpoctal232;
+
+struct QIpoctal232 {
+ QOSGraphObject obj;
+};
/* Tests only initialization so far. TODO: Replace with functional tests */
-static void nop(void)
+static void nop(void *obj, void *data, QGuestAllocator *alloc)
{
}
-int main(int argc, char **argv)
+static void *ipoctal232_create(void *pci_bus, QGuestAllocator *alloc,
+ void *addr)
{
- int ret;
+ QIpoctal232 *ipoctal232 = g_new0(QIpoctal232, 1);
- g_test_init(&argc, &argv, NULL);
- qtest_add_func("/ipoctal232/tpci200/nop", nop);
+ return &ipoctal232->obj;
+}
- qtest_start("-device tpci200,id=ipack0 -device ipoctal232,bus=ipack0.0");
- ret = g_test_run();
+static void ipoctal232_register_nodes(void)
+{
+ qos_node_create_driver("ipoctal232", ipoctal232_create);
+ qos_node_consumes("ipoctal232", "ipack", &(QOSGraphEdgeOptions) {
+ .extra_device_opts = "bus=ipack0.0",
+ });
+}
- qtest_end();
+libqos_init(ipoctal232_register_nodes);
- return ret;
+static void register_ipoctal232_test(void)
+{
+ qos_add_test("nop", "ipoctal232", nop, NULL);
}
+
+libqos_init(register_ipoctal232_test);
diff --git a/tests/ivshmem-test.c b/tests/ivshmem-test.c
index 942ddc9192..227561fbca 100644
--- a/tests/ivshmem-test.c
+++ b/tests/ivshmem-test.c
@@ -74,7 +74,7 @@ static inline unsigned in_reg(IVState *s, enum Reg reg)
unsigned res;
res = qpci_io_readl(s->dev, s->reg_bar, reg);
- g_test_message("*%s -> %x\n", name, res);
+ g_test_message("*%s -> %x", name, res);
return res;
}
@@ -83,7 +83,7 @@ static inline void out_reg(IVState *s, enum Reg reg, unsigned v)
{
const char *name = reg2str(reg);
- g_test_message("%x -> *%s\n", v, name);
+ g_test_message("%x -> *%s", v, name);
qpci_io_writel(s->dev, s->reg_bar, reg, v);
}
diff --git a/tests/libqos/aarch64-xlnx-zcu102-machine.c b/tests/libqos/aarch64-xlnx-zcu102-machine.c
new file mode 100644
index 0000000000..6fff040b37
--- /dev/null
+++ b/tests/libqos/aarch64-xlnx-zcu102-machine.c
@@ -0,0 +1,94 @@
+/*
+ * libqos driver framework
+ *
+ * Copyright (c) 2018 Emanuele Giuseppe Esposito <e.emanuelegiuseppe@gmail.com>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2 as published by the Free Software Foundation.
+ *
+ * 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 "libqos/malloc.h"
+#include "libqos/qgraph.h"
+#include "sdhci.h"
+
+typedef struct QXlnxZCU102Machine QXlnxZCU102Machine;
+
+struct QXlnxZCU102Machine {
+ QOSGraphObject obj;
+ QGuestAllocator alloc;
+ QSDHCI_MemoryMapped sdhci;
+};
+
+#define ARM_PAGE_SIZE 4096
+#define XLNX_ZCU102_RAM_ADDR 0
+#define XLNX_ZCU102_RAM_SIZE 0x20000000
+
+static void *xlnx_zcu102_get_driver(void *object, const char *interface)
+{
+ QXlnxZCU102Machine *machine = object;
+ if (!g_strcmp0(interface, "memory")) {
+ return &machine->alloc;
+ }
+
+ fprintf(stderr, "%s not present in aarch64/xlnx-zcu102\n", interface);
+ g_assert_not_reached();
+}
+
+static QOSGraphObject *xlnx_zcu102_get_device(void *obj, const char *device)
+{
+ QXlnxZCU102Machine *machine = obj;
+ if (!g_strcmp0(device, "generic-sdhci")) {
+ return &machine->sdhci.obj;
+ }
+
+ fprintf(stderr, "%s not present in aarch64/xlnx-zcu102\n", device);
+ g_assert_not_reached();
+}
+
+static void xlnx_zcu102_destructor(QOSGraphObject *obj)
+{
+ QXlnxZCU102Machine *machine = (QXlnxZCU102Machine *) obj;
+ alloc_destroy(&machine->alloc);
+}
+
+static void *qos_create_machine_aarch64_xlnx_zcu102(QTestState *qts)
+{
+ QXlnxZCU102Machine *machine = g_new0(QXlnxZCU102Machine, 1);
+
+ alloc_init(&machine->alloc, 0,
+ XLNX_ZCU102_RAM_ADDR + (1 << 20),
+ XLNX_ZCU102_RAM_ADDR + XLNX_ZCU102_RAM_SIZE,
+ ARM_PAGE_SIZE);
+
+ machine->obj.get_device = xlnx_zcu102_get_device;
+ machine->obj.get_driver = xlnx_zcu102_get_driver;
+ machine->obj.destructor = xlnx_zcu102_destructor;
+ /* Datasheet: UG1085 (v1.7) */
+ qos_init_sdhci_mm(&machine->sdhci, qts, 0xff160000, &(QSDHCIProperties) {
+ .version = 3,
+ .baseclock = 0,
+ .capab.sdma = true,
+ .capab.reg = 0x280737ec6481
+ });
+ return &machine->obj;
+}
+
+static void xlnx_zcu102_register_nodes(void)
+{
+ qos_node_create_machine("aarch64/xlnx-zcu102",
+ qos_create_machine_aarch64_xlnx_zcu102);
+ qos_node_contains("aarch64/xlnx-zcu102", "generic-sdhci", NULL);
+}
+
+libqos_init(xlnx_zcu102_register_nodes);
diff --git a/tests/libqos/ahci.c b/tests/libqos/ahci.c
index 63fbc9e3c9..cc1b08eabe 100644
--- a/tests/libqos/ahci.c
+++ b/tests/libqos/ahci.c
@@ -130,7 +130,7 @@ QPCIDevice *get_ahci_device(QTestState *qts, uint32_t *fingerprint)
uint32_t ahci_fingerprint;
QPCIBus *pcibus;
- pcibus = qpci_init_pc(qts, NULL);
+ pcibus = qpci_new_pc(qts, NULL);
/* Find the AHCI PCI device and verify it's the right one. */
ahci = qpci_device_find(pcibus, QPCI_DEVFN(0x1F, 0x02));
diff --git a/tests/libqos/arm-raspi2-machine.c b/tests/libqos/arm-raspi2-machine.c
new file mode 100644
index 0000000000..3aff670f76
--- /dev/null
+++ b/tests/libqos/arm-raspi2-machine.c
@@ -0,0 +1,91 @@
+/*
+ * libqos driver framework
+ *
+ * Copyright (c) 2018 Emanuele Giuseppe Esposito <e.emanuelegiuseppe@gmail.com>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2 as published by the Free Software Foundation.
+ *
+ * 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 "libqos/malloc.h"
+#include "libqos/qgraph.h"
+#include "sdhci.h"
+
+#define ARM_PAGE_SIZE 4096
+#define RASPI2_RAM_ADDR 0
+#define RASPI2_RAM_SIZE 0x20000000
+
+typedef struct QRaspi2Machine QRaspi2Machine;
+
+struct QRaspi2Machine {
+ QOSGraphObject obj;
+ QGuestAllocator alloc;
+ QSDHCI_MemoryMapped sdhci;
+};
+
+static void *raspi2_get_driver(void *object, const char *interface)
+{
+ QRaspi2Machine *machine = object;
+ if (!g_strcmp0(interface, "memory")) {
+ return &machine->alloc;
+ }
+
+ fprintf(stderr, "%s not present in arm/raspi2\n", interface);
+ g_assert_not_reached();
+}
+
+static QOSGraphObject *raspi2_get_device(void *obj, const char *device)
+{
+ QRaspi2Machine *machine = obj;
+ if (!g_strcmp0(device, "generic-sdhci")) {
+ return &machine->sdhci.obj;
+ }
+
+ fprintf(stderr, "%s not present in arm/raspi2\n", device);
+ g_assert_not_reached();
+}
+
+static void raspi2_destructor(QOSGraphObject *obj)
+{
+ QRaspi2Machine *machine = (QRaspi2Machine *) obj;
+ alloc_destroy(&machine->alloc);
+}
+
+static void *qos_create_machine_arm_raspi2(QTestState *qts)
+{
+ QRaspi2Machine *machine = g_new0(QRaspi2Machine, 1);
+
+ alloc_init(&machine->alloc, 0,
+ RASPI2_RAM_ADDR + (1 << 20),
+ RASPI2_RAM_ADDR + RASPI2_RAM_SIZE,
+ ARM_PAGE_SIZE);
+ machine->obj.get_device = raspi2_get_device;
+ machine->obj.get_driver = raspi2_get_driver;
+ machine->obj.destructor = raspi2_destructor;
+ qos_init_sdhci_mm(&machine->sdhci, qts, 0x3f300000, &(QSDHCIProperties) {
+ .version = 3,
+ .baseclock = 52,
+ .capab.sdma = false,
+ .capab.reg = 0x052134b4
+ });
+ return &machine->obj;
+}
+
+static void raspi2_register_nodes(void)
+{
+ qos_node_create_machine("arm/raspi2", qos_create_machine_arm_raspi2);
+ qos_node_contains("arm/raspi2", "generic-sdhci", NULL);
+}
+
+libqos_init(raspi2_register_nodes);
diff --git a/tests/libqos/arm-sabrelite-machine.c b/tests/libqos/arm-sabrelite-machine.c
new file mode 100644
index 0000000000..c4128d8686
--- /dev/null
+++ b/tests/libqos/arm-sabrelite-machine.c
@@ -0,0 +1,91 @@
+/*
+ * libqos driver framework
+ *
+ * Copyright (c) 2018 Emanuele Giuseppe Esposito <e.emanuelegiuseppe@gmail.com>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2 as published by the Free Software Foundation.
+ *
+ * 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 "libqos/malloc.h"
+#include "libqos/qgraph.h"
+#include "sdhci.h"
+
+#define ARM_PAGE_SIZE 4096
+#define SABRELITE_RAM_START 0x10000000
+#define SABRELITE_RAM_END 0x30000000
+
+typedef struct QSabreliteMachine QSabreliteMachine;
+
+struct QSabreliteMachine {
+ QOSGraphObject obj;
+ QGuestAllocator alloc;
+ QSDHCI_MemoryMapped sdhci;
+};
+
+static void *sabrelite_get_driver(void *object, const char *interface)
+{
+ QSabreliteMachine *machine = object;
+ if (!g_strcmp0(interface, "memory")) {
+ return &machine->alloc;
+ }
+
+ fprintf(stderr, "%s not present in arm/sabrelite\n", interface);
+ g_assert_not_reached();
+}
+
+static QOSGraphObject *sabrelite_get_device(void *obj, const char *device)
+{
+ QSabreliteMachine *machine = obj;
+ if (!g_strcmp0(device, "generic-sdhci")) {
+ return &machine->sdhci.obj;
+ }
+
+ fprintf(stderr, "%s not present in arm/sabrelite\n", device);
+ g_assert_not_reached();
+}
+
+static void sabrelite_destructor(QOSGraphObject *obj)
+{
+ QSabreliteMachine *machine = (QSabreliteMachine *) obj;
+ alloc_destroy(&machine->alloc);
+}
+
+static void *qos_create_machine_arm_sabrelite(QTestState *qts)
+{
+ QSabreliteMachine *machine = g_new0(QSabreliteMachine, 1);
+
+ alloc_init(&machine->alloc, 0,
+ SABRELITE_RAM_START,
+ SABRELITE_RAM_END,
+ ARM_PAGE_SIZE);
+ machine->obj.get_device = sabrelite_get_device;
+ machine->obj.get_driver = sabrelite_get_driver;
+ machine->obj.destructor = sabrelite_destructor;
+ qos_init_sdhci_mm(&machine->sdhci, qts, 0x02190000, &(QSDHCIProperties) {
+ .version = 3,
+ .baseclock = 0,
+ .capab.sdma = true,
+ .capab.reg = 0x057834b4,
+ });
+ return &machine->obj;
+}
+
+static void sabrelite_register_nodes(void)
+{
+ qos_node_create_machine("arm/sabrelite", qos_create_machine_arm_sabrelite);
+ qos_node_contains("arm/sabrelite", "generic-sdhci", NULL);
+}
+
+libqos_init(sabrelite_register_nodes);
diff --git a/tests/libqos/arm-smdkc210-machine.c b/tests/libqos/arm-smdkc210-machine.c
new file mode 100644
index 0000000000..1fb9dfc0cb
--- /dev/null
+++ b/tests/libqos/arm-smdkc210-machine.c
@@ -0,0 +1,91 @@
+/*
+ * libqos driver framework
+ *
+ * Copyright (c) 2018 Emanuele Giuseppe Esposito <e.emanuelegiuseppe@gmail.com>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2 as published by the Free Software Foundation.
+ *
+ * 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 "libqos/malloc.h"
+#include "libqos/qgraph.h"
+#include "sdhci.h"
+
+#define ARM_PAGE_SIZE 4096
+#define SMDKC210_RAM_ADDR 0x40000000ull
+#define SMDKC210_RAM_SIZE 0x40000000ull
+
+typedef struct QSmdkc210Machine QSmdkc210Machine;
+
+struct QSmdkc210Machine {
+ QOSGraphObject obj;
+ QGuestAllocator alloc;
+ QSDHCI_MemoryMapped sdhci;
+};
+
+static void *smdkc210_get_driver(void *object, const char *interface)
+{
+ QSmdkc210Machine *machine = object;
+ if (!g_strcmp0(interface, "memory")) {
+ return &machine->alloc;
+ }
+
+ fprintf(stderr, "%s not present in arm/smdkc210\n", interface);
+ g_assert_not_reached();
+}
+
+static QOSGraphObject *smdkc210_get_device(void *obj, const char *device)
+{
+ QSmdkc210Machine *machine = obj;
+ if (!g_strcmp0(device, "generic-sdhci")) {
+ return &machine->sdhci.obj;
+ }
+
+ fprintf(stderr, "%s not present in arm/smdkc210\n", device);
+ g_assert_not_reached();
+}
+
+static void smdkc210_destructor(QOSGraphObject *obj)
+{
+ QSmdkc210Machine *machine = (QSmdkc210Machine *) obj;
+ alloc_destroy(&machine->alloc);
+}
+
+static void *qos_create_machine_arm_smdkc210(QTestState *qts)
+{
+ QSmdkc210Machine *machine = g_new0(QSmdkc210Machine, 1);
+
+ alloc_init(&machine->alloc, 0,
+ SMDKC210_RAM_ADDR,
+ SMDKC210_RAM_ADDR + SMDKC210_RAM_SIZE,
+ ARM_PAGE_SIZE);
+ machine->obj.get_device = smdkc210_get_device;
+ machine->obj.get_driver = smdkc210_get_driver;
+ machine->obj.destructor = smdkc210_destructor;
+ qos_init_sdhci_mm(&machine->sdhci, qts, 0x12510000, &(QSDHCIProperties) {
+ .version = 2,
+ .baseclock = 0,
+ .capab.sdma = true,
+ .capab.reg = 0x5e80080,
+ });
+ return &machine->obj;
+}
+
+static void smdkc210_register_nodes(void)
+{
+ qos_node_create_machine("arm/smdkc210", qos_create_machine_arm_smdkc210);
+ qos_node_contains("arm/smdkc210", "generic-sdhci", NULL);
+}
+
+libqos_init(smdkc210_register_nodes);
diff --git a/tests/libqos/arm-virt-machine.c b/tests/libqos/arm-virt-machine.c
new file mode 100644
index 0000000000..2abc431ecf
--- /dev/null
+++ b/tests/libqos/arm-virt-machine.c
@@ -0,0 +1,90 @@
+/*
+ * libqos driver framework
+ *
+ * Copyright (c) 2018 Emanuele Giuseppe Esposito <e.emanuelegiuseppe@gmail.com>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2 as published by the Free Software Foundation.
+ *
+ * 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 "libqos/malloc.h"
+#include "libqos/qgraph.h"
+#include "libqos/virtio-mmio.h"
+
+#define ARM_PAGE_SIZE 4096
+#define VIRTIO_MMIO_BASE_ADDR 0x0A003E00
+#define ARM_VIRT_RAM_ADDR 0x40000000
+#define ARM_VIRT_RAM_SIZE 0x20000000
+#define VIRTIO_MMIO_SIZE 0x00000200
+
+typedef struct QVirtMachine QVirtMachine;
+
+struct QVirtMachine {
+ QOSGraphObject obj;
+ QGuestAllocator alloc;
+ QVirtioMMIODevice virtio_mmio;
+};
+
+static void virt_destructor(QOSGraphObject *obj)
+{
+ QVirtMachine *machine = (QVirtMachine *) obj;
+ alloc_destroy(&machine->alloc);
+}
+
+static void *virt_get_driver(void *object, const char *interface)
+{
+ QVirtMachine *machine = object;
+ if (!g_strcmp0(interface, "memory")) {
+ return &machine->alloc;
+ }
+
+ fprintf(stderr, "%s not present in arm/virtio\n", interface);
+ g_assert_not_reached();
+}
+
+static QOSGraphObject *virt_get_device(void *obj, const char *device)
+{
+ QVirtMachine *machine = obj;
+ if (!g_strcmp0(device, "virtio-mmio")) {
+ return &machine->virtio_mmio.obj;
+ }
+
+ fprintf(stderr, "%s not present in arm/virtio\n", device);
+ g_assert_not_reached();
+}
+
+static void *qos_create_machine_arm_virt(QTestState *qts)
+{
+ QVirtMachine *machine = g_new0(QVirtMachine, 1);
+
+ alloc_init(&machine->alloc, 0,
+ ARM_VIRT_RAM_ADDR,
+ ARM_VIRT_RAM_ADDR + ARM_VIRT_RAM_SIZE,
+ ARM_PAGE_SIZE);
+ qvirtio_mmio_init_device(&machine->virtio_mmio, qts, VIRTIO_MMIO_BASE_ADDR,
+ VIRTIO_MMIO_SIZE);
+
+ machine->obj.get_device = virt_get_device;
+ machine->obj.get_driver = virt_get_driver;
+ machine->obj.destructor = virt_destructor;
+ return machine;
+}
+
+static void virtio_mmio_register_nodes(void)
+{
+ qos_node_create_machine("arm/virt", qos_create_machine_arm_virt);
+ qos_node_contains("arm/virt", "virtio-mmio", NULL);
+}
+
+libqos_init(virtio_mmio_register_nodes);
diff --git a/tests/libqos/arm-xilinx-zynq-a9-machine.c b/tests/libqos/arm-xilinx-zynq-a9-machine.c
new file mode 100644
index 0000000000..4e199fcd48
--- /dev/null
+++ b/tests/libqos/arm-xilinx-zynq-a9-machine.c
@@ -0,0 +1,94 @@
+/*
+ * libqos driver framework
+ *
+ * Copyright (c) 2018 Emanuele Giuseppe Esposito <e.emanuelegiuseppe@gmail.com>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2 as published by the Free Software Foundation.
+ *
+ * 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 "libqos/malloc.h"
+#include "libqos/qgraph.h"
+#include "sdhci.h"
+
+typedef struct QXilinxZynqA9Machine QXilinxZynqA9Machine;
+
+struct QXilinxZynqA9Machine {
+ QOSGraphObject obj;
+ QGuestAllocator alloc;
+ QSDHCI_MemoryMapped sdhci;
+};
+
+#define ARM_PAGE_SIZE 4096
+#define XILINX_ZYNQ_A9_RAM_ADDR 0
+#define XILINX_ZYNQ_A9_RAM_SIZE 0x20000000
+
+static void *xilinx_zynq_a9_get_driver(void *object, const char *interface)
+{
+ QXilinxZynqA9Machine *machine = object;
+ if (!g_strcmp0(interface, "memory")) {
+ return &machine->alloc;
+ }
+
+ fprintf(stderr, "%s not present in arm/xilinx-zynq-a9\n", interface);
+ g_assert_not_reached();
+}
+
+static QOSGraphObject *xilinx_zynq_a9_get_device(void *obj, const char *device)
+{
+ QXilinxZynqA9Machine *machine = obj;
+ if (!g_strcmp0(device, "generic-sdhci")) {
+ return &machine->sdhci.obj;
+ }
+
+ fprintf(stderr, "%s not present in arm/xilinx-zynq-a9\n", device);
+ g_assert_not_reached();
+}
+
+static void xilinx_zynq_a9_destructor(QOSGraphObject *obj)
+{
+ QXilinxZynqA9Machine *machine = (QXilinxZynqA9Machine *) obj;
+ alloc_destroy(&machine->alloc);
+}
+
+static void *qos_create_machine_arm_xilinx_zynq_a9(QTestState *qts)
+{
+ QXilinxZynqA9Machine *machine = g_new0(QXilinxZynqA9Machine, 1);
+
+ alloc_init(&machine->alloc, 0,
+ XILINX_ZYNQ_A9_RAM_ADDR + (1 << 20),
+ XILINX_ZYNQ_A9_RAM_ADDR + XILINX_ZYNQ_A9_RAM_SIZE,
+ ARM_PAGE_SIZE);
+
+ machine->obj.get_device = xilinx_zynq_a9_get_device;
+ machine->obj.get_driver = xilinx_zynq_a9_get_driver;
+ machine->obj.destructor = xilinx_zynq_a9_destructor;
+ /* Datasheet: UG585 (v1.12.1) */
+ qos_init_sdhci_mm(&machine->sdhci, qts, 0xe0100000, &(QSDHCIProperties) {
+ .version = 2,
+ .baseclock = 0,
+ .capab.sdma = true,
+ .capab.reg = 0x69ec0080,
+ });
+ return &machine->obj;
+}
+
+static void xilinx_zynq_a9_register_nodes(void)
+{
+ qos_node_create_machine("arm/xilinx-zynq-a9",
+ qos_create_machine_arm_xilinx_zynq_a9);
+ qos_node_contains("arm/xilinx-zynq-a9", "generic-sdhci", NULL);
+}
+
+libqos_init(xilinx_zynq_a9_register_nodes);
diff --git a/tests/libqos/e1000e.c b/tests/libqos/e1000e.c
new file mode 100644
index 0000000000..54d3898899
--- /dev/null
+++ b/tests/libqos/e1000e.c
@@ -0,0 +1,260 @@
+/*
+ * libqos driver framework
+ *
+ * Copyright (c) 2018 Emanuele Giuseppe Esposito <e.emanuelegiuseppe@gmail.com>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2 as published by the Free Software Foundation.
+ *
+ * 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/qgraph.h"
+#include "e1000e.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_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_TDBAL (0x3800)
+
+#define E1000E_TDBAH (0x3804)
+#define E1000E_TDH (0x3810)
+
+#define E1000E_RDBAL (0x2800)
+#define E1000E_RDBAH (0x2804)
+#define E1000E_RDH (0x2810)
+
+#define E1000E_TXD_LEN (16)
+#define E1000E_RXD_LEN (16)
+
+static void e1000e_macreg_write(QE1000E *d, uint32_t reg, uint32_t val)
+{
+ QE1000E_PCI *d_pci = container_of(d, QE1000E_PCI, e1000e);
+ qpci_io_writel(&d_pci->pci_dev, d_pci->mac_regs, reg, val);
+}
+
+static uint32_t e1000e_macreg_read(QE1000E *d, uint32_t reg)
+{
+ QE1000E_PCI *d_pci = container_of(d, QE1000E_PCI, e1000e);
+ return qpci_io_readl(&d_pci->pci_dev, d_pci->mac_regs, reg);
+}
+
+void e1000e_tx_ring_push(QE1000E *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);
+}
+
+void e1000e_rx_ring_push(QE1000E *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_foreach_callback(QPCIDevice *dev, int devfn, void *data)
+{
+ QPCIDevice *res = data;
+ memcpy(res, dev, sizeof(QPCIDevice));
+ g_free(dev);
+}
+
+void e1000e_wait_isr(QE1000E *d, uint16_t msg_id)
+{
+ QE1000E_PCI *d_pci = container_of(d, QE1000E_PCI, e1000e);
+ guint64 end_time = g_get_monotonic_time() + 5 * G_TIME_SPAN_SECOND;
+
+ do {
+ if (qpci_msix_pending(&d_pci->pci_dev, msg_id)) {
+ return;
+ }
+ clock_step(10000);
+ } while (g_get_monotonic_time() < end_time);
+
+ g_error("Timeout expired");
+}
+
+static void e1000e_pci_destructor(QOSGraphObject *obj)
+{
+ QE1000E_PCI *epci = (QE1000E_PCI *) obj;
+ qpci_iounmap(&epci->pci_dev, epci->mac_regs);
+ qpci_msix_disable(&epci->pci_dev);
+}
+
+static void e1000e_pci_start_hw(QOSGraphObject *obj)
+{
+ QE1000E_PCI *d = (QE1000E_PCI *) obj;
+ uint32_t val;
+
+ /* Enable the device */
+ qpci_device_enable(&d->pci_dev);
+
+ /* Reset the device */
+ val = e1000e_macreg_read(&d->e1000e, E1000E_CTRL);
+ e1000e_macreg_write(&d->e1000e, E1000E_CTRL, val | E1000E_CTRL_RESET);
+
+ /* Enable and configure MSI-X */
+ qpci_msix_enable(&d->pci_dev);
+ e1000e_macreg_write(&d->e1000e, E1000E_IVAR, E1000E_IVAR_TEST_CFG);
+
+ /* Check the device status - link and speed */
+ val = e1000e_macreg_read(&d->e1000e, 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, E1000E_RCTL, 0);
+ e1000e_macreg_write(&d->e1000e, E1000E_TCTL, 0);
+
+ /* Notify the device that the driver is ready */
+ val = e1000e_macreg_read(&d->e1000e, E1000E_CTRL_EXT);
+ e1000e_macreg_write(&d->e1000e, E1000E_CTRL_EXT,
+ val | E1000E_CTRL_EXT_DRV_LOAD | E1000E_CTRL_EXT_TXLSFLOW);
+
+ e1000e_macreg_write(&d->e1000e, E1000E_TDBAL,
+ (uint32_t) d->e1000e.tx_ring);
+ e1000e_macreg_write(&d->e1000e, E1000E_TDBAH,
+ (uint32_t) (d->e1000e.tx_ring >> 32));
+ e1000e_macreg_write(&d->e1000e, E1000E_TDLEN, E1000E_RING_LEN);
+ e1000e_macreg_write(&d->e1000e, E1000E_TDT, 0);
+ e1000e_macreg_write(&d->e1000e, E1000E_TDH, 0);
+
+ /* Enable transmit */
+ e1000e_macreg_write(&d->e1000e, E1000E_TCTL, E1000E_TCTL_EN);
+ e1000e_macreg_write(&d->e1000e, E1000E_RDBAL,
+ (uint32_t)d->e1000e.rx_ring);
+ e1000e_macreg_write(&d->e1000e, E1000E_RDBAH,
+ (uint32_t)(d->e1000e.rx_ring >> 32));
+ e1000e_macreg_write(&d->e1000e, E1000E_RDLEN, E1000E_RING_LEN);
+ e1000e_macreg_write(&d->e1000e, E1000E_RDT, 0);
+ e1000e_macreg_write(&d->e1000e, E1000E_RDH, 0);
+
+ /* Enable receive */
+ e1000e_macreg_write(&d->e1000e, E1000E_RFCTL, E1000E_RFCTL_EXTEN);
+ e1000e_macreg_write(&d->e1000e, E1000E_RCTL, E1000E_RCTL_EN |
+ E1000E_RCTL_UPE |
+ E1000E_RCTL_MPE);
+
+ /* Enable all interrupts */
+ e1000e_macreg_write(&d->e1000e, E1000E_IMS, 0xFFFFFFFF);
+
+}
+
+static void *e1000e_pci_get_driver(void *obj, const char *interface)
+{
+ QE1000E_PCI *epci = obj;
+ if (!g_strcmp0(interface, "e1000e-if")) {
+ return &epci->e1000e;
+ }
+
+ /* implicit contains */
+ if (!g_strcmp0(interface, "pci-device")) {
+ return &epci->pci_dev;
+ }
+
+ fprintf(stderr, "%s not present in e1000e\n", interface);
+ g_assert_not_reached();
+}
+
+static void *e1000e_pci_create(void *pci_bus, QGuestAllocator *alloc,
+ void *addr)
+{
+ QE1000E_PCI *d = g_new0(QE1000E_PCI, 1);
+ QPCIBus *bus = pci_bus;
+ QPCIAddress *address = addr;
+
+ qpci_device_foreach(bus, address->vendor_id, address->device_id,
+ e1000e_foreach_callback, &d->pci_dev);
+
+ /* Map BAR0 (mac registers) */
+ d->mac_regs = qpci_iomap(&d->pci_dev, 0, NULL);
+
+ /* Allocate and setup TX ring */
+ d->e1000e.tx_ring = guest_alloc(alloc, E1000E_RING_LEN);
+ g_assert(d->e1000e.tx_ring != 0);
+
+ /* Allocate and setup RX ring */
+ d->e1000e.rx_ring = guest_alloc(alloc, E1000E_RING_LEN);
+ g_assert(d->e1000e.rx_ring != 0);
+
+ d->obj.get_driver = e1000e_pci_get_driver;
+ d->obj.start_hw = e1000e_pci_start_hw;
+ d->obj.destructor = e1000e_pci_destructor;
+
+ return &d->obj;
+}
+
+static void e1000e_register_nodes(void)
+{
+ QPCIAddress addr = {
+ .vendor_id = 0x8086,
+ .device_id = 0x10D3,
+ };
+
+ /* FIXME: every test using this node needs to setup a -netdev socket,id=hs0
+ * otherwise QEMU is not going to start */
+ QOSGraphEdgeOptions opts = {
+ .extra_device_opts = "netdev=hs0",
+ };
+ add_qpci_address(&opts, &addr);
+
+ qos_node_create_driver("e1000e", e1000e_pci_create);
+ qos_node_consumes("e1000e", "pci-bus", &opts);
+}
+
+libqos_init(e1000e_register_nodes);
diff --git a/tests/libqos/e1000e.h b/tests/libqos/e1000e.h
new file mode 100644
index 0000000000..9d37094f43
--- /dev/null
+++ b/tests/libqos/e1000e.h
@@ -0,0 +1,53 @@
+/*
+ * libqos driver framework
+ *
+ * Copyright (c) 2018 Emanuele Giuseppe Esposito <e.emanuelegiuseppe@gmail.com>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2 as published by the Free Software Foundation.
+ *
+ * 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 QGRAPH_E1000E
+#define QGRAPH_E1000E
+
+#include "libqos/qgraph.h"
+#include "pci.h"
+
+#define E1000E_RX0_MSG_ID (0)
+#define E1000E_TX0_MSG_ID (1)
+#define E1000E_OTHER_MSG_ID (2)
+
+#define E1000E_TDLEN (0x3808)
+#define E1000E_TDT (0x3818)
+#define E1000E_RDLEN (0x2808)
+#define E1000E_RDT (0x2818)
+
+typedef struct QE1000E QE1000E;
+typedef struct QE1000E_PCI QE1000E_PCI;
+
+struct QE1000E {
+ uint64_t tx_ring;
+ uint64_t rx_ring;
+};
+
+struct QE1000E_PCI {
+ QOSGraphObject obj;
+ QPCIDevice pci_dev;
+ QPCIBar mac_regs;
+ QE1000E e1000e;
+};
+
+void e1000e_wait_isr(QE1000E *d, uint16_t msg_id);
+void e1000e_tx_ring_push(QE1000E *d, void *descr);
+void e1000e_rx_ring_push(QE1000E *d, void *descr);
+
+#endif
diff --git a/tests/libqos/libqos-pc.c b/tests/libqos/libqos-pc.c
index a9c1aceaa7..d04abc548b 100644
--- a/tests/libqos/libqos-pc.c
+++ b/tests/libqos/libqos-pc.c
@@ -4,9 +4,8 @@
#include "libqos/pci-pc.h"
static QOSOps qos_ops = {
- .init_allocator = pc_alloc_init_flags,
- .uninit_allocator = pc_alloc_uninit,
- .qpci_init = qpci_init_pc,
+ .alloc_init = pc_alloc_init,
+ .qpci_new = qpci_new_pc,
.qpci_free = qpci_free_pc,
.shutdown = qtest_pc_shutdown,
};
diff --git a/tests/libqos/libqos-spapr.c b/tests/libqos/libqos-spapr.c
index a37791e5d0..8766d543ce 100644
--- a/tests/libqos/libqos-spapr.c
+++ b/tests/libqos/libqos-spapr.c
@@ -4,9 +4,8 @@
#include "libqos/pci-spapr.h"
static QOSOps qos_ops = {
- .init_allocator = spapr_alloc_init_flags,
- .uninit_allocator = spapr_alloc_uninit,
- .qpci_init = qpci_init_spapr,
+ .alloc_init = spapr_alloc_init,
+ .qpci_new = qpci_new_spapr,
.qpci_free = qpci_free_spapr,
.shutdown = qtest_spapr_shutdown,
};
diff --git a/tests/libqos/libqos.c b/tests/libqos/libqos.c
index c514187344..636a111a6f 100644
--- a/tests/libqos/libqos.c
+++ b/tests/libqos/libqos.c
@@ -24,8 +24,8 @@ QOSState *qtest_vboot(QOSOps *ops, const char *cmdline_fmt, va_list ap)
qs->qts = qtest_init(cmdline);
qs->ops = ops;
if (ops) {
- qs->alloc = ops->init_allocator(qs->qts, ALLOC_NO_FLAGS);
- qs->pcibus = ops->qpci_init(qs->qts, qs->alloc);
+ ops->alloc_init(&qs->alloc, qs->qts, ALLOC_NO_FLAGS);
+ qs->pcibus = ops->qpci_new(qs->qts, &qs->alloc);
}
g_free(cmdline);
@@ -58,11 +58,8 @@ void qtest_common_shutdown(QOSState *qs)
qs->ops->qpci_free(qs->pcibus);
qs->pcibus = NULL;
}
- if (qs->alloc && qs->ops->uninit_allocator) {
- qs->ops->uninit_allocator(qs->alloc);
- qs->alloc = NULL;
- }
}
+ alloc_destroy(&qs->alloc);
qtest_quit(qs->qts);
g_free(qs);
}
@@ -116,7 +113,7 @@ void migrate(QOSState *from, QOSState *to, const char *uri)
/* If we were running, we can wait for an event. */
if (running) {
- migrate_allocator(from->alloc, to->alloc);
+ migrate_allocator(&from->alloc, &to->alloc);
set_context(to);
qtest_qmp_eventwait(to->qts, "RESUME");
return;
@@ -146,7 +143,7 @@ void migrate(QOSState *from, QOSState *to, const char *uri)
g_assert_not_reached();
}
- migrate_allocator(from->alloc, to->alloc);
+ migrate_allocator(&from->alloc, &to->alloc);
set_context(to);
}
diff --git a/tests/libqos/libqos.h b/tests/libqos/libqos.h
index 07d4b93d1d..149b0be8bc 100644
--- a/tests/libqos/libqos.h
+++ b/tests/libqos/libqos.h
@@ -3,21 +3,20 @@
#include "libqtest.h"
#include "libqos/pci.h"
-#include "libqos/malloc-pc.h"
+#include "libqos/malloc.h"
typedef struct QOSState QOSState;
typedef struct QOSOps {
- QGuestAllocator *(*init_allocator)(QTestState *qts, QAllocOpts);
- void (*uninit_allocator)(QGuestAllocator *);
- QPCIBus *(*qpci_init)(QTestState *qts, QGuestAllocator *alloc);
+ void (*alloc_init)(QGuestAllocator *, QTestState *, QAllocOpts);
+ QPCIBus *(*qpci_new)(QTestState *qts, QGuestAllocator *alloc);
void (*qpci_free)(QPCIBus *bus);
void (*shutdown)(QOSState *);
} QOSOps;
struct QOSState {
QTestState *qts;
- QGuestAllocator *alloc;
+ QGuestAllocator alloc;
QPCIBus *pcibus;
QOSOps *ops;
};
@@ -36,12 +35,12 @@ void generate_pattern(void *buffer, size_t len, size_t cycle_len);
static inline uint64_t qmalloc(QOSState *q, size_t bytes)
{
- return guest_alloc(q->alloc, bytes);
+ return guest_alloc(&q->alloc, bytes);
}
static inline void qfree(QOSState *q, uint64_t addr)
{
- guest_free(q->alloc, addr);
+ guest_free(&q->alloc, addr);
}
#endif
diff --git a/tests/libqos/malloc-generic.c b/tests/libqos/malloc-generic.c
deleted file mode 100644
index 33ce90b925..0000000000
--- a/tests/libqos/malloc-generic.c
+++ /dev/null
@@ -1,39 +0,0 @@
-/*
- * Basic libqos generic malloc support
- *
- * Copyright (c) 2014 Marc Marí
- *
- * 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 "libqos/malloc-generic.h"
-#include "libqos/malloc.h"
-
-/*
- * Mostly for valgrind happiness, but it does offer
- * a chokepoint for debugging guest memory leaks, too.
- */
-void generic_alloc_uninit(QGuestAllocator *allocator)
-{
- alloc_uninit(allocator);
-}
-
-QGuestAllocator *generic_alloc_init_flags(uint64_t base_addr, uint64_t size,
- uint32_t page_size, QAllocOpts flags)
-{
- QGuestAllocator *s;
- uint64_t start = base_addr + (1 << 20); /* Start at 1MB */
-
- s = alloc_init_flags(flags, start, start + size);
- alloc_set_page_size(s, page_size);
-
- return s;
-}
-
-inline QGuestAllocator *generic_alloc_init(uint64_t base_addr, uint64_t size,
- uint32_t page_size)
-{
- return generic_alloc_init_flags(base_addr, size, page_size, ALLOC_NO_FLAGS);
-}
diff --git a/tests/libqos/malloc-generic.h b/tests/libqos/malloc-generic.h
deleted file mode 100644
index 90104ecec9..0000000000
--- a/tests/libqos/malloc-generic.h
+++ /dev/null
@@ -1,21 +0,0 @@
-/*
- * Basic libqos generic malloc support
- *
- * Copyright (c) 2014 Marc Marí
- *
- * 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 LIBQOS_MALLOC_GENERIC_H
-#define LIBQOS_MALLOC_GENERIC_H
-
-#include "libqos/malloc.h"
-
-QGuestAllocator *generic_alloc_init(uint64_t base_addr, uint64_t size,
- uint32_t page_size);
-QGuestAllocator *generic_alloc_init_flags(uint64_t base_addr, uint64_t size,
- uint32_t page_size, QAllocOpts flags);
-void generic_alloc_uninit(QGuestAllocator *allocator);
-
-#endif
diff --git a/tests/libqos/malloc-pc.c b/tests/libqos/malloc-pc.c
index b83cb8f0af..949a99361d 100644
--- a/tests/libqos/malloc-pc.c
+++ b/tests/libqos/malloc-pc.c
@@ -20,32 +20,14 @@
#define PAGE_SIZE (4096)
-/*
- * Mostly for valgrind happiness, but it does offer
- * a chokepoint for debugging guest memory leaks, too.
- */
-void pc_alloc_uninit(QGuestAllocator *allocator)
-{
- alloc_uninit(allocator);
-}
-
-QGuestAllocator *pc_alloc_init_flags(QTestState *qts, QAllocOpts flags)
+void pc_alloc_init(QGuestAllocator *s, QTestState *qts, QAllocOpts flags)
{
- QGuestAllocator *s;
uint64_t ram_size;
QFWCFG *fw_cfg = pc_fw_cfg_init(qts);
ram_size = qfw_cfg_get_u64(fw_cfg, FW_CFG_RAM_SIZE);
- s = alloc_init_flags(flags, 1 << 20, MIN(ram_size, 0xE0000000));
- alloc_set_page_size(s, PAGE_SIZE);
+ alloc_init(s, flags, 1 << 20, MIN(ram_size, 0xE0000000), PAGE_SIZE);
/* clean-up */
g_free(fw_cfg);
-
- return s;
-}
-
-inline QGuestAllocator *pc_alloc_init(QTestState *qts)
-{
- return pc_alloc_init_flags(qts, ALLOC_NO_FLAGS);
}
diff --git a/tests/libqos/malloc-pc.h b/tests/libqos/malloc-pc.h
index 10f3da6cf2..21e75ae004 100644
--- a/tests/libqos/malloc-pc.h
+++ b/tests/libqos/malloc-pc.h
@@ -15,8 +15,6 @@
#include "libqos/malloc.h"
-QGuestAllocator *pc_alloc_init(QTestState *qts);
-QGuestAllocator *pc_alloc_init_flags(QTestState *qts, QAllocOpts flags);
-void pc_alloc_uninit(QGuestAllocator *allocator);
+void pc_alloc_init(QGuestAllocator *s, QTestState *qts, QAllocOpts flags);
#endif
diff --git a/tests/libqos/malloc-spapr.c b/tests/libqos/malloc-spapr.c
index 1c359cea6c..2a6b7e3776 100644
--- a/tests/libqos/malloc-spapr.c
+++ b/tests/libqos/malloc-spapr.c
@@ -17,22 +17,7 @@
*/
#define SPAPR_MIN_SIZE 0x10000000
-void spapr_alloc_uninit(QGuestAllocator *allocator)
+void spapr_alloc_init(QGuestAllocator *s, QTestState *qts, QAllocOpts flags)
{
- alloc_uninit(allocator);
-}
-
-QGuestAllocator *spapr_alloc_init_flags(QTestState *qts, QAllocOpts flags)
-{
- QGuestAllocator *s;
-
- s = alloc_init_flags(flags, 1 << 20, SPAPR_MIN_SIZE);
- alloc_set_page_size(s, PAGE_SIZE);
-
- return s;
-}
-
-QGuestAllocator *spapr_alloc_init(void)
-{
- return spapr_alloc_init_flags(NULL, ALLOC_NO_FLAGS);
+ alloc_init(s, flags, 1 << 20, SPAPR_MIN_SIZE, PAGE_SIZE);
}
diff --git a/tests/libqos/malloc-spapr.h b/tests/libqos/malloc-spapr.h
index 52a9346a26..e5fe9bfc4b 100644
--- a/tests/libqos/malloc-spapr.h
+++ b/tests/libqos/malloc-spapr.h
@@ -10,8 +10,6 @@
#include "libqos/malloc.h"
-QGuestAllocator *spapr_alloc_init(void);
-QGuestAllocator *spapr_alloc_init_flags(QTestState *qts, QAllocOpts flags);
-void spapr_alloc_uninit(QGuestAllocator *allocator);
+void spapr_alloc_init(QGuestAllocator *s, QTestState *qts, QAllocOpts flags);
#endif
diff --git a/tests/libqos/malloc.c b/tests/libqos/malloc.c
index f7bae47a08..615422a5c4 100644
--- a/tests/libqos/malloc.c
+++ b/tests/libqos/malloc.c
@@ -15,24 +15,12 @@
#include "qemu-common.h"
#include "qemu/host-utils.h"
-typedef QTAILQ_HEAD(MemList, MemBlock) MemList;
-
typedef struct MemBlock {
QTAILQ_ENTRY(MemBlock) MLIST_ENTNAME;
uint64_t size;
uint64_t addr;
} MemBlock;
-struct QGuestAllocator {
- QAllocOpts opts;
- uint64_t start;
- uint64_t end;
- uint32_t page_size;
-
- MemList *used;
- MemList *free;
-};
-
#define DEFAULT_PAGE_SIZE 4096
static void mlist_delete(MemList *list, MemBlock *node)
@@ -225,7 +213,7 @@ static void mlist_free(QGuestAllocator *s, uint64_t addr)
* Mostly for valgrind happiness, but it does offer
* a chokepoint for debugging guest memory leaks, too.
*/
-void alloc_uninit(QGuestAllocator *allocator)
+void alloc_destroy(QGuestAllocator *allocator)
{
MemBlock *node;
MemBlock *tmp;
@@ -261,7 +249,6 @@ void alloc_uninit(QGuestAllocator *allocator)
g_free(allocator->used);
g_free(allocator->free);
- g_free(allocator);
}
uint64_t guest_alloc(QGuestAllocator *allocator, size_t size)
@@ -297,11 +284,13 @@ void guest_free(QGuestAllocator *allocator, uint64_t addr)
}
}
-QGuestAllocator *alloc_init(uint64_t start, uint64_t end)
+void alloc_init(QGuestAllocator *s, QAllocOpts opts,
+ uint64_t start, uint64_t end,
+ size_t page_size)
{
- QGuestAllocator *s = g_malloc0(sizeof(*s));
MemBlock *node;
+ s->opts = opts;
s->start = start;
s->end = end;
@@ -313,26 +302,7 @@ QGuestAllocator *alloc_init(uint64_t start, uint64_t end)
node = mlist_new(s->start, s->end - s->start);
QTAILQ_INSERT_HEAD(s->free, node, MLIST_ENTNAME);
- s->page_size = DEFAULT_PAGE_SIZE;
-
- return s;
-}
-
-QGuestAllocator *alloc_init_flags(QAllocOpts opts,
- uint64_t start, uint64_t end)
-{
- QGuestAllocator *s = alloc_init(start, end);
- s->opts = opts;
- return s;
-}
-
-void alloc_set_page_size(QGuestAllocator *allocator, size_t page_size)
-{
- /* Can't alter the page_size for an allocator in-use */
- g_assert(QTAILQ_EMPTY(allocator->used));
-
- g_assert(is_power_of_2(page_size));
- allocator->page_size = page_size;
+ s->page_size = page_size;
}
void alloc_set_flags(QGuestAllocator *allocator, QAllocOpts opts)
diff --git a/tests/libqos/malloc.h b/tests/libqos/malloc.h
index 828fddabdb..4d1a2e2bef 100644
--- a/tests/libqos/malloc.h
+++ b/tests/libqos/malloc.h
@@ -23,19 +23,28 @@ typedef enum {
ALLOC_PARANOID = 0x04
} QAllocOpts;
-typedef struct QGuestAllocator QGuestAllocator;
+typedef QTAILQ_HEAD(MemList, MemBlock) MemList;
-void alloc_uninit(QGuestAllocator *allocator);
+typedef struct QGuestAllocator {
+ QAllocOpts opts;
+ uint64_t start;
+ uint64_t end;
+ uint32_t page_size;
+
+ MemList *used;
+ MemList *free;
+} QGuestAllocator;
/* Always returns page aligned values */
uint64_t guest_alloc(QGuestAllocator *allocator, size_t size);
void guest_free(QGuestAllocator *allocator, uint64_t addr);
void migrate_allocator(QGuestAllocator *src, QGuestAllocator *dst);
-QGuestAllocator *alloc_init(uint64_t start, uint64_t end);
-QGuestAllocator *alloc_init_flags(QAllocOpts flags,
- uint64_t start, uint64_t end);
-void alloc_set_page_size(QGuestAllocator *allocator, size_t page_size);
void alloc_set_flags(QGuestAllocator *allocator, QAllocOpts opts);
+void alloc_init(QGuestAllocator *alloc, QAllocOpts flags,
+ uint64_t start, uint64_t end,
+ size_t page_size);
+void alloc_destroy(QGuestAllocator *allocator);
+
#endif
diff --git a/tests/libqos/pci-pc.c b/tests/libqos/pci-pc.c
index a4fc02b5d8..4ab16facf2 100644
--- a/tests/libqos/pci-pc.c
+++ b/tests/libqos/pci-pc.c
@@ -18,15 +18,9 @@
#include "qemu-common.h"
-
#define ACPI_PCIHP_ADDR 0xae00
#define PCI_EJ_BASE 0x0008
-typedef struct QPCIBusPC
-{
- QPCIBus bus;
-} QPCIBusPC;
-
static uint8_t qpci_pc_pio_readb(QPCIBus *bus, uint32_t addr)
{
return qtest_inb(bus->qts, addr);
@@ -116,44 +110,68 @@ static void qpci_pc_config_writel(QPCIBus *bus, int devfn, uint8_t offset, uint3
qtest_outl(bus->qts, 0xcfc, value);
}
-QPCIBus *qpci_init_pc(QTestState *qts, QGuestAllocator *alloc)
+static void *qpci_pc_get_driver(void *obj, const char *interface)
{
- QPCIBusPC *ret = g_new0(QPCIBusPC, 1);
+ QPCIBusPC *qpci = obj;
+ if (!g_strcmp0(interface, "pci-bus")) {
+ return &qpci->bus;
+ }
+ fprintf(stderr, "%s not present in pci-bus-pc\n", interface);
+ g_assert_not_reached();
+}
+void qpci_init_pc(QPCIBusPC *qpci, QTestState *qts, QGuestAllocator *alloc)
+{
assert(qts);
- ret->bus.pio_readb = qpci_pc_pio_readb;
- ret->bus.pio_readw = qpci_pc_pio_readw;
- ret->bus.pio_readl = qpci_pc_pio_readl;
- ret->bus.pio_readq = qpci_pc_pio_readq;
+ /* tests can use pci-bus */
+ qpci->bus.has_buggy_msi = FALSE;
+
+ qpci->bus.pio_readb = qpci_pc_pio_readb;
+ qpci->bus.pio_readw = qpci_pc_pio_readw;
+ qpci->bus.pio_readl = qpci_pc_pio_readl;
+ qpci->bus.pio_readq = qpci_pc_pio_readq;
- ret->bus.pio_writeb = qpci_pc_pio_writeb;
- ret->bus.pio_writew = qpci_pc_pio_writew;
- ret->bus.pio_writel = qpci_pc_pio_writel;
- ret->bus.pio_writeq = qpci_pc_pio_writeq;
+ qpci->bus.pio_writeb = qpci_pc_pio_writeb;
+ qpci->bus.pio_writew = qpci_pc_pio_writew;
+ qpci->bus.pio_writel = qpci_pc_pio_writel;
+ qpci->bus.pio_writeq = qpci_pc_pio_writeq;
- ret->bus.memread = qpci_pc_memread;
- ret->bus.memwrite = qpci_pc_memwrite;
+ qpci->bus.memread = qpci_pc_memread;
+ qpci->bus.memwrite = qpci_pc_memwrite;
- ret->bus.config_readb = qpci_pc_config_readb;
- ret->bus.config_readw = qpci_pc_config_readw;
- ret->bus.config_readl = qpci_pc_config_readl;
+ qpci->bus.config_readb = qpci_pc_config_readb;
+ qpci->bus.config_readw = qpci_pc_config_readw;
+ qpci->bus.config_readl = qpci_pc_config_readl;
- ret->bus.config_writeb = qpci_pc_config_writeb;
- ret->bus.config_writew = qpci_pc_config_writew;
- ret->bus.config_writel = qpci_pc_config_writel;
+ qpci->bus.config_writeb = qpci_pc_config_writeb;
+ qpci->bus.config_writew = qpci_pc_config_writew;
+ qpci->bus.config_writel = qpci_pc_config_writel;
- ret->bus.qts = qts;
- ret->bus.pio_alloc_ptr = 0xc000;
- ret->bus.mmio_alloc_ptr = 0xE0000000;
- ret->bus.mmio_limit = 0x100000000ULL;
+ qpci->bus.qts = qts;
+ qpci->bus.pio_alloc_ptr = 0xc000;
+ qpci->bus.mmio_alloc_ptr = 0xE0000000;
+ qpci->bus.mmio_limit = 0x100000000ULL;
- return &ret->bus;
+ qpci->obj.get_driver = qpci_pc_get_driver;
+}
+
+QPCIBus *qpci_new_pc(QTestState *qts, QGuestAllocator *alloc)
+{
+ QPCIBusPC *qpci = g_new0(QPCIBusPC, 1);
+ qpci_init_pc(qpci, qts, alloc);
+
+ return &qpci->bus;
}
void qpci_free_pc(QPCIBus *bus)
{
- QPCIBusPC *s = container_of(bus, QPCIBusPC, bus);
+ QPCIBusPC *s;
+
+ if (!bus) {
+ return;
+ }
+ s = container_of(bus, QPCIBusPC, bus);
g_free(s);
}
@@ -172,3 +190,11 @@ void qpci_unplug_acpi_device_test(const char *id, uint8_t slot)
qmp_eventwait("DEVICE_DELETED");
}
+
+static void qpci_pc_register_nodes(void)
+{
+ qos_node_create_driver("pci-bus-pc", NULL);
+ qos_node_produces("pci-bus-pc", "pci-bus");
+}
+
+libqos_init(qpci_pc_register_nodes);
diff --git a/tests/libqos/pci-pc.h b/tests/libqos/pci-pc.h
index 491eeac756..4690005232 100644
--- a/tests/libqos/pci-pc.h
+++ b/tests/libqos/pci-pc.h
@@ -15,8 +15,35 @@
#include "libqos/pci.h"
#include "libqos/malloc.h"
+#include "libqos/qgraph.h"
+
+typedef struct QPCIBusPC {
+ QOSGraphObject obj;
+ QPCIBus bus;
+} QPCIBusPC;
+
+/* qpci_init_pc():
+ * @ret: A valid QPCIBusPC * pointer
+ * @qts: The %QTestState for this PC machine
+ * @alloc: A previously initialized @alloc providing memory for @qts
+ *
+ * This function initializes an already allocated
+ * QPCIBusPC object.
+ */
+void qpci_init_pc(QPCIBusPC *ret, QTestState *qts, QGuestAllocator *alloc);
+
+/* qpci_pc_new():
+ * @qts: The %QTestState for this PC machine
+ * @alloc: A previously initialized @alloc providing memory for @qts
+ *
+ * This function creates a new QPCIBusPC object,
+ * and properly initialize its fields.
+ *
+ * Returns the QPCIBus *bus field of a newly
+ * allocated QPCIBusPC.
+ */
+QPCIBus *qpci_new_pc(QTestState *qts, QGuestAllocator *alloc);
-QPCIBus *qpci_init_pc(QTestState *qts, QGuestAllocator *alloc);
void qpci_free_pc(QPCIBus *bus);
#endif
diff --git a/tests/libqos/pci-spapr.c b/tests/libqos/pci-spapr.c
index 4c29889b0b..6925925997 100644
--- a/tests/libqos/pci-spapr.c
+++ b/tests/libqos/pci-spapr.c
@@ -9,33 +9,13 @@
#include "libqtest.h"
#include "libqos/pci-spapr.h"
#include "libqos/rtas.h"
+#include "libqos/qgraph.h"
#include "hw/pci/pci_regs.h"
#include "qemu-common.h"
#include "qemu/host-utils.h"
-
-/* From include/hw/pci-host/spapr.h */
-
-typedef struct QPCIWindow {
- uint64_t pci_base; /* window address in PCI space */
- uint64_t size; /* window size */
-} QPCIWindow;
-
-typedef struct QPCIBusSPAPR {
- QPCIBus bus;
- QGuestAllocator *alloc;
-
- uint64_t buid;
-
- uint64_t pio_cpu_base;
- QPCIWindow pio;
-
- uint64_t mmio32_cpu_base;
- QPCIWindow mmio32;
-} QPCIBusSPAPR;
-
/*
* PCI devices are always little-endian
* SPAPR by default is big-endian
@@ -160,60 +140,93 @@ static void qpci_spapr_config_writel(QPCIBus *bus, int devfn, uint8_t offset,
#define SPAPR_PCI_MMIO32_WIN_SIZE 0x80000000 /* 2 GiB */
#define SPAPR_PCI_IO_WIN_SIZE 0x10000
-QPCIBus *qpci_init_spapr(QTestState *qts, QGuestAllocator *alloc)
+static void *qpci_spapr_get_driver(void *obj, const char *interface)
{
- QPCIBusSPAPR *ret = g_new0(QPCIBusSPAPR, 1);
+ QPCIBusSPAPR *qpci = obj;
+ if (!g_strcmp0(interface, "pci-bus")) {
+ return &qpci->bus;
+ }
+ fprintf(stderr, "%s not present in pci-bus-spapr", interface);
+ g_assert_not_reached();
+}
+void qpci_init_spapr(QPCIBusSPAPR *qpci, QTestState *qts,
+ QGuestAllocator *alloc)
+{
assert(qts);
- ret->alloc = alloc;
+ /* tests cannot use spapr, needs to be fixed first */
+ qpci->bus.has_buggy_msi = TRUE;
+
+ qpci->alloc = alloc;
- ret->bus.pio_readb = qpci_spapr_pio_readb;
- ret->bus.pio_readw = qpci_spapr_pio_readw;
- ret->bus.pio_readl = qpci_spapr_pio_readl;
- ret->bus.pio_readq = qpci_spapr_pio_readq;
+ qpci->bus.pio_readb = qpci_spapr_pio_readb;
+ qpci->bus.pio_readw = qpci_spapr_pio_readw;
+ qpci->bus.pio_readl = qpci_spapr_pio_readl;
+ qpci->bus.pio_readq = qpci_spapr_pio_readq;
- ret->bus.pio_writeb = qpci_spapr_pio_writeb;
- ret->bus.pio_writew = qpci_spapr_pio_writew;
- ret->bus.pio_writel = qpci_spapr_pio_writel;
- ret->bus.pio_writeq = qpci_spapr_pio_writeq;
+ qpci->bus.pio_writeb = qpci_spapr_pio_writeb;
+ qpci->bus.pio_writew = qpci_spapr_pio_writew;
+ qpci->bus.pio_writel = qpci_spapr_pio_writel;
+ qpci->bus.pio_writeq = qpci_spapr_pio_writeq;
- ret->bus.memread = qpci_spapr_memread;
- ret->bus.memwrite = qpci_spapr_memwrite;
+ qpci->bus.memread = qpci_spapr_memread;
+ qpci->bus.memwrite = qpci_spapr_memwrite;
- ret->bus.config_readb = qpci_spapr_config_readb;
- ret->bus.config_readw = qpci_spapr_config_readw;
- ret->bus.config_readl = qpci_spapr_config_readl;
+ qpci->bus.config_readb = qpci_spapr_config_readb;
+ qpci->bus.config_readw = qpci_spapr_config_readw;
+ qpci->bus.config_readl = qpci_spapr_config_readl;
- ret->bus.config_writeb = qpci_spapr_config_writeb;
- ret->bus.config_writew = qpci_spapr_config_writew;
- ret->bus.config_writel = qpci_spapr_config_writel;
+ qpci->bus.config_writeb = qpci_spapr_config_writeb;
+ qpci->bus.config_writew = qpci_spapr_config_writew;
+ qpci->bus.config_writel = qpci_spapr_config_writel;
/* FIXME: We assume the default location of the PHB for now.
* Ideally we'd parse the device tree deposited in the guest to
* get the window locations */
- ret->buid = 0x800000020000000ULL;
+ qpci->buid = 0x800000020000000ULL;
- ret->pio_cpu_base = SPAPR_PCI_BASE;
- ret->pio.pci_base = 0;
- ret->pio.size = SPAPR_PCI_IO_WIN_SIZE;
+ qpci->pio_cpu_base = SPAPR_PCI_BASE;
+ qpci->pio.pci_base = 0;
+ qpci->pio.size = SPAPR_PCI_IO_WIN_SIZE;
/* 32-bit portion of the MMIO window is at PCI address 2..4 GiB */
- ret->mmio32_cpu_base = SPAPR_PCI_BASE;
- ret->mmio32.pci_base = SPAPR_PCI_MMIO32_WIN_SIZE;
- ret->mmio32.size = SPAPR_PCI_MMIO32_WIN_SIZE;
+ qpci->mmio32_cpu_base = SPAPR_PCI_BASE;
+ qpci->mmio32.pci_base = SPAPR_PCI_MMIO32_WIN_SIZE;
+ qpci->mmio32.size = SPAPR_PCI_MMIO32_WIN_SIZE;
- ret->bus.qts = qts;
- ret->bus.pio_alloc_ptr = 0xc000;
- ret->bus.mmio_alloc_ptr = ret->mmio32.pci_base;
- ret->bus.mmio_limit = ret->mmio32.pci_base + ret->mmio32.size;
+ qpci->bus.qts = qts;
+ qpci->bus.pio_alloc_ptr = 0xc000;
+ qpci->bus.mmio_alloc_ptr = qpci->mmio32.pci_base;
+ qpci->bus.mmio_limit = qpci->mmio32.pci_base + qpci->mmio32.size;
- return &ret->bus;
+ qpci->obj.get_driver = qpci_spapr_get_driver;
+}
+
+QPCIBus *qpci_new_spapr(QTestState *qts, QGuestAllocator *alloc)
+{
+ QPCIBusSPAPR *qpci = g_new0(QPCIBusSPAPR, 1);
+ qpci_init_spapr(qpci, qts, alloc);
+
+ return &qpci->bus;
}
void qpci_free_spapr(QPCIBus *bus)
{
- QPCIBusSPAPR *s = container_of(bus, QPCIBusSPAPR, bus);
+ QPCIBusSPAPR *s;
+
+ if (!bus) {
+ return;
+ }
+ s = container_of(bus, QPCIBusSPAPR, bus);
g_free(s);
}
+
+static void qpci_spapr_register_nodes(void)
+{
+ qos_node_create_driver("pci-bus-spapr", NULL);
+ qos_node_produces("pci-bus-spapr", "pci-bus");
+}
+
+libqos_init(qpci_spapr_register_nodes);
diff --git a/tests/libqos/pci-spapr.h b/tests/libqos/pci-spapr.h
index 387686dfc8..d9e25631c6 100644
--- a/tests/libqos/pci-spapr.h
+++ b/tests/libqos/pci-spapr.h
@@ -10,8 +10,32 @@
#include "libqos/malloc.h"
#include "libqos/pci.h"
+#include "libqos/qgraph.h"
-QPCIBus *qpci_init_spapr(QTestState *qts, QGuestAllocator *alloc);
+/* From include/hw/pci-host/spapr.h */
+
+typedef struct QPCIWindow {
+ uint64_t pci_base; /* window address in PCI space */
+ uint64_t size; /* window size */
+} QPCIWindow;
+
+typedef struct QPCIBusSPAPR {
+ QOSGraphObject obj;
+ QPCIBus bus;
+ QGuestAllocator *alloc;
+
+ uint64_t buid;
+
+ uint64_t pio_cpu_base;
+ QPCIWindow pio;
+
+ uint64_t mmio32_cpu_base;
+ QPCIWindow mmio32;
+} QPCIBusSPAPR;
+
+void qpci_init_spapr(QPCIBusSPAPR *ret, QTestState *qts,
+ QGuestAllocator *alloc);
+QPCIBus *qpci_new_spapr(QTestState *qts, QGuestAllocator *alloc);
void qpci_free_spapr(QPCIBus *bus);
#endif
diff --git a/tests/libqos/pci.c b/tests/libqos/pci.c
index e8c342c257..662ee7a517 100644
--- a/tests/libqos/pci.c
+++ b/tests/libqos/pci.c
@@ -15,6 +15,7 @@
#include "hw/pci/pci_regs.h"
#include "qemu/host-utils.h"
+#include "libqos/qgraph.h"
void qpci_device_foreach(QPCIBus *bus, int vendor_id, int device_id,
void (*func)(QPCIDevice *dev, int devfn, void *data),
@@ -50,13 +51,34 @@ void qpci_device_foreach(QPCIBus *bus, int vendor_id, int device_id,
}
}
+bool qpci_has_buggy_msi(QPCIDevice *dev)
+{
+ return dev->bus->has_buggy_msi;
+}
+
+bool qpci_check_buggy_msi(QPCIDevice *dev)
+{
+ if (qpci_has_buggy_msi(dev)) {
+ g_test_skip("Skipping due to incomplete support for MSI");
+ return true;
+ }
+ return false;
+}
+
+static void qpci_device_set(QPCIDevice *dev, QPCIBus *bus, int devfn)
+{
+ g_assert(dev);
+
+ dev->bus = bus;
+ dev->devfn = devfn;
+}
+
QPCIDevice *qpci_device_find(QPCIBus *bus, int devfn)
{
QPCIDevice *dev;
dev = g_malloc0(sizeof(*dev));
- dev->bus = bus;
- dev->devfn = devfn;
+ qpci_device_set(dev, bus, devfn);
if (qpci_config_readw(dev, PCI_VENDOR_ID) == 0xFFFF) {
g_free(dev);
@@ -66,6 +88,17 @@ QPCIDevice *qpci_device_find(QPCIBus *bus, int devfn)
return dev;
}
+void qpci_device_init(QPCIDevice *dev, QPCIBus *bus, QPCIAddress *addr)
+{
+ uint16_t vendor_id, device_id;
+
+ qpci_device_set(dev, bus, addr->devfn);
+ vendor_id = qpci_config_readw(dev, PCI_VENDOR_ID);
+ device_id = qpci_config_readw(dev, PCI_DEVICE_ID);
+ g_assert(!addr->vendor_id || vendor_id == addr->vendor_id);
+ g_assert(!addr->device_id || device_id == addr->device_id);
+}
+
void qpci_device_enable(QPCIDevice *dev)
{
uint16_t cmd;
@@ -395,3 +428,12 @@ QPCIBar qpci_legacy_iomap(QPCIDevice *dev, uint16_t addr)
QPCIBar bar = { .addr = addr };
return bar;
}
+
+void add_qpci_address(QOSGraphEdgeOptions *opts, QPCIAddress *addr)
+{
+ g_assert(addr);
+ g_assert(opts);
+
+ opts->arg = addr;
+ opts->size_arg = sizeof(QPCIAddress);
+}
diff --git a/tests/libqos/pci.h b/tests/libqos/pci.h
index 0b7e936174..8e1d292a7d 100644
--- a/tests/libqos/pci.h
+++ b/tests/libqos/pci.h
@@ -14,6 +14,7 @@
#define LIBQOS_PCI_H
#include "libqtest.h"
+#include "libqos/qgraph.h"
#define QPCI_PIO_LIMIT 0x10000
@@ -22,6 +23,7 @@
typedef struct QPCIDevice QPCIDevice;
typedef struct QPCIBus QPCIBus;
typedef struct QPCIBar QPCIBar;
+typedef struct QPCIAddress QPCIAddress;
struct QPCIBus {
uint8_t (*pio_readb)(QPCIBus *bus, uint32_t addr);
@@ -51,6 +53,8 @@ struct QPCIBus {
QTestState *qts;
uint16_t pio_alloc_ptr;
uint64_t mmio_alloc_ptr, mmio_limit;
+ bool has_buggy_msi; /* TRUE for spapr, FALSE for pci */
+
};
struct QPCIBar {
@@ -66,10 +70,20 @@ struct QPCIDevice
uint64_t msix_table_off, msix_pba_off;
};
+struct QPCIAddress {
+ uint32_t devfn;
+ uint16_t vendor_id;
+ uint16_t device_id;
+};
+
void qpci_device_foreach(QPCIBus *bus, int vendor_id, int device_id,
void (*func)(QPCIDevice *dev, int devfn, void *data),
void *data);
QPCIDevice *qpci_device_find(QPCIBus *bus, int devfn);
+void qpci_device_init(QPCIDevice *dev, QPCIBus *bus, QPCIAddress *addr);
+
+bool qpci_has_buggy_msi(QPCIDevice *dev);
+bool qpci_check_buggy_msi(QPCIDevice *dev);
void qpci_device_enable(QPCIDevice *dev);
uint8_t qpci_find_capability(QPCIDevice *dev, uint8_t id);
@@ -110,4 +124,6 @@ void qpci_iounmap(QPCIDevice *dev, QPCIBar addr);
QPCIBar qpci_legacy_iomap(QPCIDevice *dev, uint16_t addr);
void qpci_unplug_acpi_device_test(const char *id, uint8_t slot);
+
+void add_qpci_address(QOSGraphEdgeOptions *opts, QPCIAddress *addr);
#endif
diff --git a/tests/libqos/ppc64_pseries-machine.c b/tests/libqos/ppc64_pseries-machine.c
new file mode 100644
index 0000000000..2f3640010d
--- /dev/null
+++ b/tests/libqos/ppc64_pseries-machine.c
@@ -0,0 +1,111 @@
+/*
+ * libqos driver framework
+ *
+ * Copyright (c) 2018 Emanuele Giuseppe Esposito <e.emanuelegiuseppe@gmail.com>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2 as published by the Free Software Foundation.
+ *
+ * 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 "libqos/qgraph.h"
+#include "pci-spapr.h"
+#include "libqos/malloc-spapr.h"
+
+typedef struct QSPAPR_pci_host QSPAPR_pci_host;
+typedef struct Qppc64_pseriesMachine Qppc64_pseriesMachine;
+
+struct QSPAPR_pci_host {
+ QOSGraphObject obj;
+ QPCIBusSPAPR pci;
+};
+
+struct Qppc64_pseriesMachine {
+ QOSGraphObject obj;
+ QGuestAllocator alloc;
+ QSPAPR_pci_host bridge;
+};
+
+/* QSPAPR_pci_host */
+
+static QOSGraphObject *QSPAPR_host_get_device(void *obj, const char *device)
+{
+ QSPAPR_pci_host *host = obj;
+ if (!g_strcmp0(device, "pci-bus-spapr")) {
+ return &host->pci.obj;
+ }
+ fprintf(stderr, "%s not present in QSPAPR_pci_host\n", device);
+ g_assert_not_reached();
+}
+
+static void qos_create_QSPAPR_host(QSPAPR_pci_host *host,
+ QTestState *qts,
+ QGuestAllocator *alloc)
+{
+ host->obj.get_device = QSPAPR_host_get_device;
+ qpci_init_spapr(&host->pci, qts, alloc);
+}
+
+/* ppc64/pseries machine */
+
+static void spapr_destructor(QOSGraphObject *obj)
+{
+ Qppc64_pseriesMachine *machine = (Qppc64_pseriesMachine *) obj;
+ alloc_destroy(&machine->alloc);
+}
+
+static void *spapr_get_driver(void *object, const char *interface)
+{
+ Qppc64_pseriesMachine *machine = object;
+ if (!g_strcmp0(interface, "memory")) {
+ return &machine->alloc;
+ }
+
+ fprintf(stderr, "%s not present in ppc64/pseries\n", interface);
+ g_assert_not_reached();
+}
+
+static QOSGraphObject *spapr_get_device(void *obj, const char *device)
+{
+ Qppc64_pseriesMachine *machine = obj;
+ if (!g_strcmp0(device, "spapr-pci-host-bridge")) {
+ return &machine->bridge.obj;
+ }
+
+ fprintf(stderr, "%s not present in ppc64/pseries\n", device);
+ g_assert_not_reached();
+}
+
+static void *qos_create_machine_spapr(QTestState *qts)
+{
+ Qppc64_pseriesMachine *machine = g_new0(Qppc64_pseriesMachine, 1);
+ machine->obj.get_device = spapr_get_device;
+ machine->obj.get_driver = spapr_get_driver;
+ machine->obj.destructor = spapr_destructor;
+ spapr_alloc_init(&machine->alloc, qts, ALLOC_NO_FLAGS);
+
+ qos_create_QSPAPR_host(&machine->bridge, qts, &machine->alloc);
+
+ return &machine->obj;
+}
+
+static void spapr_machine_register_nodes(void)
+{
+ qos_node_create_machine("ppc64/pseries", qos_create_machine_spapr);
+ qos_node_create_driver("spapr-pci-host-bridge", NULL);
+ qos_node_contains("ppc64/pseries", "spapr-pci-host-bridge", NULL);
+ qos_node_contains("spapr-pci-host-bridge", "pci-bus-spapr", NULL);
+}
+
+libqos_init(spapr_machine_register_nodes);
+
diff --git a/tests/libqos/qgraph.c b/tests/libqos/qgraph.c
new file mode 100644
index 0000000000..122efc1b7b
--- /dev/null
+++ b/tests/libqos/qgraph.c
@@ -0,0 +1,753 @@
+/*
+ * libqos driver framework
+ *
+ * Copyright (c) 2018 Emanuele Giuseppe Esposito <e.emanuelegiuseppe@gmail.com>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2 as published by the Free Software Foundation.
+ *
+ * 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/queue.h"
+#include "libqos/qgraph_internal.h"
+#include "libqos/qgraph.h"
+
+#define QGRAPH_PRINT_DEBUG 0
+#define QOS_ROOT ""
+typedef struct QOSStackElement QOSStackElement;
+
+/* Graph Edge.*/
+struct QOSGraphEdge {
+ QOSEdgeType type;
+ char *dest;
+ void *arg; /* just for QEDGE_CONTAINS
+ * and QEDGE_CONSUMED_BY */
+ char *extra_device_opts; /* added to -device option, "," is
+ * automatically added
+ */
+ char *before_cmd_line; /* added before node cmd_line */
+ char *after_cmd_line; /* added after -device options */
+ char *edge_name; /* used by QEDGE_CONTAINS */
+ QSLIST_ENTRY(QOSGraphEdge) edge_list;
+};
+
+typedef QSLIST_HEAD(, QOSGraphEdge) QOSGraphEdgeList;
+
+/**
+ * Stack used to keep track of the discovered path when using
+ * the DFS algorithm
+ */
+struct QOSStackElement {
+ QOSGraphNode *node;
+ QOSStackElement *parent;
+ QOSGraphEdge *parent_edge;
+ int length;
+};
+
+/* Each enty in these hash table will consist of <string, node/edge> pair. */
+static GHashTable *edge_table;
+static GHashTable *node_table;
+
+/* stack used by the DFS algorithm to store the path from machine to test */
+static QOSStackElement qos_node_stack[QOS_PATH_MAX_ELEMENT_SIZE];
+static int qos_node_tos;
+
+/**
+ * add_edge(): creates an edge of type @type
+ * from @source to @dest node, and inserts it in the
+ * edges hash table
+ *
+ * Nodes @source and @dest do not necessarily need to exist.
+ * Possibility to add also options (see #QOSGraphEdgeOptions)
+ * edge->edge_name is used as identifier for get_device relationships,
+ * so by default is equal to @dest.
+ */
+static void add_edge(const char *source, const char *dest,
+ QOSEdgeType type, QOSGraphEdgeOptions *opts)
+{
+ char *key;
+ QOSGraphEdgeList *list = g_hash_table_lookup(edge_table, source);
+
+ if (!list) {
+ list = g_new0(QOSGraphEdgeList, 1);
+ key = g_strdup(source);
+ g_hash_table_insert(edge_table, key, list);
+ }
+
+ if (!opts) {
+ opts = &(QOSGraphEdgeOptions) { };
+ }
+
+ QOSGraphEdge *edge = g_new0(QOSGraphEdge, 1);
+ edge->type = type;
+ edge->dest = g_strdup(dest);
+ edge->edge_name = g_strdup(opts->edge_name ?: dest);
+ edge->arg = g_memdup(opts->arg, opts->size_arg);
+
+ edge->before_cmd_line =
+ opts->before_cmd_line ? g_strconcat(" ", opts->before_cmd_line, NULL) : NULL;
+ edge->extra_device_opts =
+ opts->extra_device_opts ? g_strconcat(",", opts->extra_device_opts, NULL) : NULL;
+ edge->after_cmd_line =
+ opts->after_cmd_line ? g_strconcat(" ", opts->after_cmd_line, NULL) : NULL;
+
+ QSLIST_INSERT_HEAD(list, edge, edge_list);
+}
+
+/* destroy_edges(): frees all edges inside a given @list */
+static void destroy_edges(void *list)
+{
+ QOSGraphEdge *temp;
+ QOSGraphEdgeList *elist = list;
+
+ while (!QSLIST_EMPTY(elist)) {
+ temp = QSLIST_FIRST(elist);
+ QSLIST_REMOVE_HEAD(elist, edge_list);
+ g_free(temp->dest);
+ g_free(temp->before_cmd_line);
+ g_free(temp->after_cmd_line);
+ g_free(temp->extra_device_opts);
+ g_free(temp->edge_name);
+ g_free(temp->arg);
+ g_free(temp);
+ }
+ g_free(elist);
+}
+
+/**
+ * create_node(): creates a node @name of type @type
+ * and inserts it to the nodes hash table.
+ * By default, node is not available.
+ */
+static QOSGraphNode *create_node(const char *name, QOSNodeType type)
+{
+ if (g_hash_table_lookup(node_table, name)) {
+ g_printerr("Node %s already created\n", name);
+ abort();
+ }
+
+ QOSGraphNode *node = g_new0(QOSGraphNode, 1);
+ node->type = type;
+ node->available = false;
+ node->name = g_strdup(name);
+ g_hash_table_insert(node_table, node->name, node);
+ return node;
+}
+
+/**
+ * destroy_node(): frees a node @val from the nodes hash table.
+ * Note that node->name is not free'd since it will represent the
+ * hash table key
+ */
+static void destroy_node(void *val)
+{
+ QOSGraphNode *node = val;
+ g_free(node->command_line);
+ g_free(node);
+}
+
+/**
+ * destroy_string(): frees @key from the nodes hash table.
+ * Actually frees the node->name
+ */
+static void destroy_string(void *key)
+{
+ g_free(key);
+}
+
+/**
+ * search_node(): search for a node @key in the nodes hash table
+ * Returns the QOSGraphNode if found, #NULL otherwise
+ */
+static QOSGraphNode *search_node(const char *key)
+{
+ return g_hash_table_lookup(node_table, key);
+}
+
+/**
+ * get_edgelist(): returns the edge list (value) assigned to
+ * the @key in the edge hash table.
+ * This list will contain all edges with source equal to @key
+ *
+ * Returns: on success: the %QOSGraphEdgeList
+ * otherwise: abort()
+ */
+static QOSGraphEdgeList *get_edgelist(const char *key)
+{
+ return g_hash_table_lookup(edge_table, key);
+}
+
+/**
+ * search_list_edges(): search for an edge with destination @dest
+ * in the given @edgelist.
+ *
+ * Returns: on success: the %QOSGraphEdge
+ * otherwise: #NULL
+ */
+static QOSGraphEdge *search_list_edges(QOSGraphEdgeList *edgelist,
+ const char *dest)
+{
+ QOSGraphEdge *tmp, *next;
+ if (!edgelist) {
+ return NULL;
+ }
+ QSLIST_FOREACH_SAFE(tmp, edgelist, edge_list, next) {
+ if (g_strcmp0(tmp->dest, dest) == 0) {
+ break;
+ }
+ }
+ return tmp;
+}
+
+/**
+ * search_machine(): search for a machine @name in the node hash
+ * table. A machine is the child of the root node.
+ * This function forces the research in the childs of the root,
+ * to check the node is a proper machine
+ *
+ * Returns: on success: the %QOSGraphNode
+ * otherwise: #NULL
+ */
+static QOSGraphNode *search_machine(const char *name)
+{
+ QOSGraphNode *n;
+ QOSGraphEdgeList *root_list = get_edgelist(QOS_ROOT);
+ QOSGraphEdge *e = search_list_edges(root_list, name);
+ if (!e) {
+ return NULL;
+ }
+ n = search_node(e->dest);
+ if (n->type == QNODE_MACHINE) {
+ return n;
+ }
+ return NULL;
+}
+
+/**
+ * create_interface(): checks if there is already
+ * a node @node in the node hash table, if not
+ * creates a node @node of type #QNODE_INTERFACE
+ * and inserts it. If there is one, check it's
+ * a #QNODE_INTERFACE and abort() if it's not.
+ */
+static void create_interface(const char *node)
+{
+ QOSGraphNode *interface;
+ interface = search_node(node);
+ if (!interface) {
+ create_node(node, QNODE_INTERFACE);
+ } else if (interface->type != QNODE_INTERFACE) {
+ fprintf(stderr, "Error: Node %s is not an interface\n", node);
+ abort();
+ }
+}
+
+/**
+ * build_machine_cmd_line(): builds the command line for the machine
+ * @node. The node name must be a valid qemu identifier, since it
+ * will be used to build the command line.
+ *
+ * It is also possible to pass an optional @args that will be
+ * concatenated to the command line.
+ *
+ * For machines, prepend -M to the machine name. ", @rgs" is added
+ * after the -M <machine> command.
+ */
+static void build_machine_cmd_line(QOSGraphNode *node, const char *args)
+{
+ char *machine = qos_get_machine_type(node->name);
+ if (args) {
+ node->command_line = g_strconcat("-M ", machine, ",", args, NULL);
+ } else {
+ node->command_line = g_strconcat("-M ", machine, " ", NULL);
+ }
+}
+
+/**
+ * build_driver_cmd_line(): builds the command line for the driver
+ * @node. The node name must be a valid qemu identifier, since it
+ * will be used to build the command line.
+ *
+ * Driver do not need additional command line, since it will be
+ * provided by the edge options.
+ *
+ * For drivers, prepend -device to the node name.
+ */
+static void build_driver_cmd_line(QOSGraphNode *node)
+{
+ node->command_line = g_strconcat(" -device ", node->name, NULL);
+}
+
+/* qos_print_cb(): callback prints all path found by the DFS algorithm. */
+static void qos_print_cb(QOSGraphNode *path, int length)
+{
+ #if QGRAPH_PRINT_DEBUG
+ printf("%d elements\n", length);
+
+ if (!path) {
+ return;
+ }
+
+ while (path->path_edge) {
+ printf("%s ", path->name);
+ switch (path->path_edge->type) {
+ case QEDGE_PRODUCES:
+ printf("--PRODUCES--> ");
+ break;
+ case QEDGE_CONSUMED_BY:
+ printf("--CONSUMED_BY--> ");
+ break;
+ case QEDGE_CONTAINS:
+ printf("--CONTAINS--> ");
+ break;
+ }
+ path = search_node(path->path_edge->dest);
+ }
+
+ printf("%s\n\n", path->name);
+ #endif
+}
+
+/* qos_push(): push a node @el and edge @e in the qos_node_stack */
+static void qos_push(QOSGraphNode *el, QOSStackElement *parent,
+ QOSGraphEdge *e)
+{
+ int len = 0; /* root is not counted */
+ if (qos_node_tos == QOS_PATH_MAX_ELEMENT_SIZE) {
+ g_printerr("QOSStack: full stack, cannot push");
+ abort();
+ }
+
+ if (parent) {
+ len = parent->length + 1;
+ }
+ qos_node_stack[qos_node_tos++] = (QOSStackElement) {
+ .node = el,
+ .parent = parent,
+ .parent_edge = e,
+ .length = len,
+ };
+}
+
+/* qos_tos(): returns the top of stack, without popping */
+static QOSStackElement *qos_tos(void)
+{
+ return &qos_node_stack[qos_node_tos - 1];
+}
+
+/* qos_pop(): pops an element from the tos, setting it unvisited*/
+static QOSStackElement *qos_pop(void)
+{
+ if (qos_node_tos == 0) {
+ g_printerr("QOSStack: empty stack, cannot pop");
+ abort();
+ }
+ QOSStackElement *e = qos_tos();
+ e->node->visited = false;
+ qos_node_tos--;
+ return e;
+}
+
+/**
+ * qos_reverse_path(): reverses the found path, going from
+ * test-to-machine to machine-to-test
+ */
+static QOSGraphNode *qos_reverse_path(QOSStackElement *el)
+{
+ if (!el) {
+ return NULL;
+ }
+
+ el->node->path_edge = NULL;
+
+ while (el->parent) {
+ el->parent->node->path_edge = el->parent_edge;
+ el = el->parent;
+ }
+
+ return el->node;
+}
+
+/**
+ * qos_traverse_graph(): graph-walking algorithm, using Depth First Search it
+ * starts from the root @machine and walks all possible path until it
+ * reaches a test node.
+ * At that point, it reverses the path found and invokes the @callback.
+ *
+ * Being Depth First Search, time complexity is O(|V| + |E|), while
+ * space is O(|V|). In this case, the maximum stack size is set by
+ * QOS_PATH_MAX_ELEMENT_SIZE.
+ */
+static void qos_traverse_graph(QOSGraphNode *root, QOSTestCallback callback)
+{
+ QOSGraphNode *v, *dest_node, *path;
+ QOSStackElement *s_el;
+ QOSGraphEdge *e, *next;
+ QOSGraphEdgeList *list;
+
+ qos_push(root, NULL, NULL);
+
+ while (qos_node_tos > 0) {
+ s_el = qos_tos();
+ v = s_el->node;
+ if (v->visited) {
+ qos_pop();
+ continue;
+ }
+ v->visited = true;
+ list = get_edgelist(v->name);
+ if (!list) {
+ qos_pop();
+ if (v->type == QNODE_TEST) {
+ v->visited = false;
+ path = qos_reverse_path(s_el);
+ callback(path, s_el->length);
+ }
+ } else {
+ QSLIST_FOREACH_SAFE(e, list, edge_list, next) {
+ dest_node = search_node(e->dest);
+
+ if (!dest_node) {
+ fprintf(stderr, "node %s in %s -> %s does not exist\n",
+ e->dest, v->name, e->dest);
+ abort();
+ }
+
+ if (!dest_node->visited && dest_node->available) {
+ qos_push(dest_node, s_el, e);
+ }
+ }
+ }
+ }
+}
+
+/* QGRAPH API*/
+
+QOSGraphNode *qos_graph_get_node(const char *key)
+{
+ return search_node(key);
+}
+
+bool qos_graph_has_node(const char *node)
+{
+ QOSGraphNode *n = search_node(node);
+ return n != NULL;
+}
+
+QOSNodeType qos_graph_get_node_type(const char *node)
+{
+ QOSGraphNode *n = search_node(node);
+ if (n) {
+ return n->type;
+ }
+ return -1;
+}
+
+bool qos_graph_get_node_availability(const char *node)
+{
+ QOSGraphNode *n = search_node(node);
+ if (n) {
+ return n->available;
+ }
+ return false;
+}
+
+QOSGraphEdge *qos_graph_get_edge(const char *node, const char *dest)
+{
+ QOSGraphEdgeList *list = get_edgelist(node);
+ return search_list_edges(list, dest);
+}
+
+QOSEdgeType qos_graph_edge_get_type(QOSGraphEdge *edge)
+{
+ if (!edge) {
+ return -1;
+ }
+ return edge->type;;
+}
+
+char *qos_graph_edge_get_dest(QOSGraphEdge *edge)
+{
+ if (!edge) {
+ return NULL;
+ }
+ return edge->dest;
+}
+
+void *qos_graph_edge_get_arg(QOSGraphEdge *edge)
+{
+ if (!edge) {
+ return NULL;
+ }
+ return edge->arg;
+}
+
+char *qos_graph_edge_get_after_cmd_line(QOSGraphEdge *edge)
+{
+ if (!edge) {
+ return NULL;
+ }
+ return edge->after_cmd_line;
+}
+
+char *qos_graph_edge_get_before_cmd_line(QOSGraphEdge *edge)
+{
+ if (!edge) {
+ return NULL;
+ }
+ return edge->before_cmd_line;
+}
+
+char *qos_graph_edge_get_extra_device_opts(QOSGraphEdge *edge)
+{
+ if (!edge) {
+ return NULL;
+ }
+ return edge->extra_device_opts;
+}
+
+char *qos_graph_edge_get_name(QOSGraphEdge *edge)
+{
+ if (!edge) {
+ return NULL;
+ }
+ return edge->edge_name;
+}
+
+bool qos_graph_has_edge(const char *start, const char *dest)
+{
+ QOSGraphEdgeList *list = get_edgelist(start);
+ QOSGraphEdge *e = search_list_edges(list, dest);
+ return e != NULL;
+}
+
+QOSGraphNode *qos_graph_get_machine(const char *node)
+{
+ return search_machine(node);
+}
+
+bool qos_graph_has_machine(const char *node)
+{
+ QOSGraphNode *m = search_machine(node);
+ return m != NULL;
+}
+
+void qos_print_graph(void)
+{
+ qos_graph_foreach_test_path(qos_print_cb);
+}
+
+void qos_graph_init(void)
+{
+ if (!node_table) {
+ node_table = g_hash_table_new_full(g_str_hash, g_str_equal,
+ destroy_string, destroy_node);
+ create_node(QOS_ROOT, QNODE_DRIVER);
+ }
+
+ if (!edge_table) {
+ edge_table = g_hash_table_new_full(g_str_hash, g_str_equal,
+ destroy_string, destroy_edges);
+ }
+}
+
+void qos_graph_destroy(void)
+{
+ if (node_table) {
+ g_hash_table_destroy(node_table);
+ }
+
+ if (edge_table) {
+ g_hash_table_destroy(edge_table);
+ }
+
+ node_table = NULL;
+ edge_table = NULL;
+}
+
+void qos_node_destroy(void *key)
+{
+ g_hash_table_remove(node_table, key);
+}
+
+void qos_edge_destroy(void *key)
+{
+ g_hash_table_remove(edge_table, key);
+}
+
+void qos_add_test(const char *name, const char *interface,
+ QOSTestFunc test_func, QOSGraphTestOptions *opts)
+{
+ QOSGraphNode *node;
+ char *test_name = g_strdup_printf("%s-tests/%s", interface, name);;
+
+ if (!opts) {
+ opts = &(QOSGraphTestOptions) { };
+ }
+ node = create_node(test_name, QNODE_TEST);
+ node->u.test.function = test_func;
+ node->u.test.arg = opts->arg;
+ assert(!opts->edge.arg);
+ assert(!opts->edge.size_arg);
+
+ node->u.test.before = opts->before;
+ node->u.test.subprocess = opts->subprocess;
+ node->available = true;
+ add_edge(interface, test_name, QEDGE_CONSUMED_BY, &opts->edge);
+ g_free(test_name);
+}
+
+void qos_node_create_machine(const char *name, QOSCreateMachineFunc function)
+{
+ qos_node_create_machine_args(name, function, NULL);
+}
+
+void qos_node_create_machine_args(const char *name,
+ QOSCreateMachineFunc function,
+ const char *opts)
+{
+ QOSGraphNode *node = create_node(name, QNODE_MACHINE);
+ build_machine_cmd_line(node, opts);
+ node->u.machine.constructor = function;
+ add_edge(QOS_ROOT, name, QEDGE_CONTAINS, NULL);
+}
+
+void qos_node_create_driver(const char *name, QOSCreateDriverFunc function)
+{
+ QOSGraphNode *node = create_node(name, QNODE_DRIVER);
+ build_driver_cmd_line(node);
+ node->u.driver.constructor = function;
+}
+
+void qos_node_contains(const char *container, const char *contained,
+ ...)
+{
+ va_list va;
+ va_start(va, contained);
+ QOSGraphEdgeOptions *opts;
+
+ do {
+ opts = va_arg(va, QOSGraphEdgeOptions *);
+ add_edge(container, contained, QEDGE_CONTAINS, opts);
+ } while (opts != NULL);
+
+ va_end(va);
+}
+
+void qos_node_produces(const char *producer, const char *interface)
+{
+ create_interface(interface);
+ add_edge(producer, interface, QEDGE_PRODUCES, NULL);
+}
+
+void qos_node_consumes(const char *consumer, const char *interface,
+ QOSGraphEdgeOptions *opts)
+{
+ create_interface(interface);
+ add_edge(interface, consumer, QEDGE_CONSUMED_BY, opts);
+}
+
+void qos_graph_node_set_availability(const char *node, bool av)
+{
+ QOSGraphEdgeList *elist;
+ QOSGraphNode *n = search_node(node);
+ QOSGraphEdge *e, *next;
+ if (!n) {
+ return;
+ }
+ n->available = av;
+ elist = get_edgelist(node);
+ if (!elist) {
+ return;
+ }
+ QSLIST_FOREACH_SAFE(e, elist, edge_list, next) {
+ if (e->type == QEDGE_CONTAINS || e->type == QEDGE_PRODUCES) {
+ qos_graph_node_set_availability(e->dest, av);
+ }
+ }
+}
+
+void qos_graph_foreach_test_path(QOSTestCallback fn)
+{
+ QOSGraphNode *root = qos_graph_get_node(QOS_ROOT);
+ qos_traverse_graph(root, fn);
+}
+
+QOSGraphObject *qos_machine_new(QOSGraphNode *node, QTestState *qts)
+{
+ QOSGraphObject *obj;
+
+ g_assert(node->type == QNODE_MACHINE);
+ obj = node->u.machine.constructor(qts);
+ obj->free = g_free;
+ return obj;
+}
+
+QOSGraphObject *qos_driver_new(QOSGraphNode *node, QOSGraphObject *parent,
+ QGuestAllocator *alloc, void *arg)
+{
+ QOSGraphObject *obj;
+
+ g_assert(node->type == QNODE_DRIVER);
+ obj = node->u.driver.constructor(parent, alloc, arg);
+ obj->free = g_free;
+ return obj;
+}
+
+void qos_object_destroy(QOSGraphObject *obj)
+{
+ if (!obj) {
+ return;
+ }
+ if (obj->destructor) {
+ obj->destructor(obj);
+ }
+ if (obj->free) {
+ obj->free(obj);
+ }
+}
+
+void qos_object_queue_destroy(QOSGraphObject *obj)
+{
+ g_test_queue_destroy((GDestroyNotify) qos_object_destroy, obj);
+}
+
+void qos_object_start_hw(QOSGraphObject *obj)
+{
+ if (obj->start_hw) {
+ obj->start_hw(obj);
+ }
+}
+
+char *qos_get_machine_type(char *name)
+{
+ while (*name != '\0' && *name != '/') {
+ name++;
+ }
+
+ if (!*name || !name[1]) {
+ fprintf(stderr, "Machine name has to be of the form <arch>/<machine>\n");
+ abort();
+ }
+
+ return name + 1;
+}
+
+void qos_delete_cmd_line(const char *name)
+{
+ QOSGraphNode *node = search_node(name);
+ if (node) {
+ g_free(node->command_line);
+ node->command_line = NULL;
+ }
+}
diff --git a/tests/libqos/qgraph.h b/tests/libqos/qgraph.h
new file mode 100644
index 0000000000..ef0c73837a
--- /dev/null
+++ b/tests/libqos/qgraph.h
@@ -0,0 +1,575 @@
+/*
+ * libqos driver framework
+ *
+ * Copyright (c) 2018 Emanuele Giuseppe Esposito <e.emanuelegiuseppe@gmail.com>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2 as published by the Free Software Foundation.
+ *
+ * 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 QGRAPH_H
+#define QGRAPH_H
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <stdbool.h>
+#include <gmodule.h>
+#include <glib.h>
+#include "qemu/module.h"
+#include "malloc.h"
+
+/* maximum path length */
+#define QOS_PATH_MAX_ELEMENT_SIZE 50
+
+typedef struct QOSGraphObject QOSGraphObject;
+typedef struct QOSGraphNode QOSGraphNode;
+typedef struct QOSGraphEdge QOSGraphEdge;
+typedef struct QOSGraphNodeOptions QOSGraphNodeOptions;
+typedef struct QOSGraphEdgeOptions QOSGraphEdgeOptions;
+typedef struct QOSGraphTestOptions QOSGraphTestOptions;
+
+/* Constructor for drivers, machines and test */
+typedef void *(*QOSCreateDriverFunc) (void *parent, QGuestAllocator *alloc,
+ void *addr);
+typedef void *(*QOSCreateMachineFunc) (QTestState *qts);
+typedef void (*QOSTestFunc) (void *parent, void *arg, QGuestAllocator *alloc);
+
+/* QOSGraphObject functions */
+typedef void *(*QOSGetDriver) (void *object, const char *interface);
+typedef QOSGraphObject *(*QOSGetDevice) (void *object, const char *name);
+typedef void (*QOSDestructorFunc) (QOSGraphObject *object);
+typedef void (*QOSStartFunct) (QOSGraphObject *object);
+
+/* Test options functions */
+typedef void *(*QOSBeforeTest) (GString *cmd_line, void *arg);
+
+/**
+ * SECTION: qgraph.h
+ * @title: Qtest Driver Framework
+ * @short_description: interfaces to organize drivers and tests
+ * as nodes in a graph
+ *
+ * This Qgraph API provides all basic functions to create a graph
+ * and instantiate nodes representing machines, drivers and tests
+ * representing their relations with CONSUMES, PRODUCES, and CONTAINS
+ * edges.
+ *
+ * The idea is to have a framework where each test asks for a specific
+ * driver, and the framework takes care of allocating the proper devices
+ * required and passing the correct command line arguments to QEMU.
+ *
+ * A node can be of four types:
+ * - QNODE_MACHINE: for example "arm/raspi2"
+ * - QNODE_DRIVER: for example "generic-sdhci"
+ * - QNODE_INTERFACE: for example "sdhci" (interface for all "-sdhci" drivers)
+ * an interface is not explicitly created, it will be auto-
+ * matically instantiated when a node consumes or produces
+ * it.
+ * - QNODE_TEST: for example "sdhci-test", consumes an interface and tests
+ * the functions provided
+ *
+ * Notes for the nodes:
+ * - QNODE_MACHINE: each machine struct must have a QGuestAllocator and
+ * implement get_driver to return the allocator passing
+ * "memory". The function can also return NULL if the
+ * allocator is not set.
+ * - QNODE_DRIVER: driver names must be unique, and machines and nodes
+ * planned to be "consumed" by other nodes must match QEMU
+ * drivers name, otherwise they won't be discovered
+ *
+ * An edge relation between two nodes (drivers or machines) X and Y can be:
+ * - X CONSUMES Y: Y can be plugged into X
+ * - X PRODUCES Y: X provides the interface Y
+ * - X CONTAINS Y: Y is part of X component
+ *
+ * Basic framework steps are the following:
+ * - All nodes and edges are created in their respective
+ * machine/driver/test files
+ * - The framework starts QEMU and asks for a list of available devices
+ * and machines (note that only machines and "consumed" nodes are mapped
+ * 1:1 with QEMU devices)
+ * - The framework walks the graph starting from the available machines and
+ * performs a Depth First Search for tests
+ * - Once a test is found, the path is walked again and all drivers are
+ * allocated accordingly and the final interface is passed to the test
+ * - The test is executed
+ * - Unused objects are cleaned and the path discovery is continued
+ *
+ * Depending on the QEMU binary used, only some drivers/machines will be
+ * available and only test that are reached by them will be executed.
+ *
+ * <example>
+ * <title>Creating new driver an its interface</title>
+ * <programlisting>
+ #include "libqos/qgraph.h"
+
+ struct My_driver {
+ QOSGraphObject obj;
+ Node_produced prod;
+ Node_contained cont;
+ }
+
+ static void my_destructor(QOSGraphObject *obj)
+ {
+ g_free(obj);
+ }
+
+ static void my_get_driver(void *object, const char *interface) {
+ My_driver *dev = object;
+ if (!g_strcmp0(interface, "my_interface")) {
+ return &dev->prod;
+ }
+ abort();
+ }
+
+ static void my_get_device(void *object, const char *device) {
+ My_driver *dev = object;
+ if (!g_strcmp0(device, "my_driver_contained")) {
+ return &dev->cont;
+ }
+ abort();
+ }
+
+ static void *my_driver_constructor(void *node_consumed,
+ QOSGraphObject *alloc)
+ {
+ My_driver dev = g_new(My_driver, 1);
+ // get the node pointed by the produce edge
+ dev->obj.get_driver = my_get_driver;
+ // get the node pointed by the contains
+ dev->obj.get_device = my_get_device;
+ // free the object
+ dev->obj.destructor = my_destructor;
+ do_something_with_node_consumed(node_consumed);
+ // set all fields of contained device
+ init_contained_device(&dev->cont);
+ return &dev->obj;
+ }
+
+ static void register_my_driver(void)
+ {
+ qos_node_create_driver("my_driver", my_driver_constructor);
+ // contained drivers don't need a constructor,
+ // they will be init by the parent.
+ qos_node_create_driver("my_driver_contained", NULL);
+
+ // For the sake of this example, assume machine x86_64/pc contains
+ // "other_node".
+ // This relation, along with the machine and "other_node" creation,
+ // should be defined in the x86_64_pc-machine.c file.
+ // "my_driver" will then consume "other_node"
+ qos_node_contains("my_driver", "my_driver_contained");
+ qos_node_produces("my_driver", "my_interface");
+ qos_node_consumes("my_driver", "other_node");
+ }
+ * </programlisting>
+ * </example>
+ *
+ * In the above example, all possible types of relations are created:
+ * node "my_driver" consumes, contains and produces other nodes.
+ * more specifically:
+ * x86_64/pc -->contains--> other_node <--consumes-- my_driver
+ * |
+ * my_driver_contained <--contains--+
+ * |
+ * my_interface <--produces--+
+ *
+ * or inverting the consumes edge in consumed_by:
+ *
+ * x86_64/pc -->contains--> other_node --consumed_by--> my_driver
+ * |
+ * my_driver_contained <--contains--+
+ * |
+ * my_interface <--produces--+
+ *
+ * <example>
+ * <title>Creating new test</title>
+ * <programlisting>
+ * #include "libqos/qgraph.h"
+ *
+ * static void my_test_function(void *obj, void *data)
+ * {
+ * Node_produced *interface_to_test = obj;
+ * // test interface_to_test
+ * }
+ *
+ * static void register_my_test(void)
+ * {
+ * qos_add_test("my_interface", "my_test", my_test_function);
+ * }
+ *
+ * libqos_init(register_my_test);
+ *
+ * </programlisting>
+ * </example>
+ *
+ * Here a new test is created, consuming "my_interface" node
+ * and creating a valid path from a machine to a test.
+ * Final graph will be like this:
+ * x86_64/pc -->contains--> other_node <--consumes-- my_driver
+ * |
+ * my_driver_contained <--contains--+
+ * |
+ * my_test --consumes--> my_interface <--produces--+
+ *
+ * or inverting the consumes edge in consumed_by:
+ *
+ * x86_64/pc -->contains--> other_node --consumed_by--> my_driver
+ * |
+ * my_driver_contained <--contains--+
+ * |
+ * my_test <--consumed_by-- my_interface <--produces--+
+ *
+ * Assuming there the binary is
+ * QTEST_QEMU_BINARY=x86_64-softmmu/qemu-system-x86_64
+ * a valid test path will be:
+ * "/x86_64/pc/other_node/my_driver/my_interface/my_test".
+ *
+ * Additional examples are also in libqos/test-qgraph.c
+ *
+ * Command line:
+ * Command line is built by using node names and optional arguments
+ * passed by the user when building the edges.
+ *
+ * There are three types of command line arguments:
+ * - in node : created from the node name. For example, machines will
+ * have "-M <machine>" to its command line, while devices
+ * "-device <device>". It is automatically done by the
+ * framework.
+ * - after node : added as additional argument to the node name.
+ * This argument is added optionally when creating edges,
+ * by setting the parameter @after_cmd_line and
+ * @extra_edge_opts in #QOSGraphEdgeOptions.
+ * The framework automatically adds
+ * a comma before @extra_edge_opts,
+ * because it is going to add attributes
+ * after the destination node pointed by
+ * the edge containing these options, and automatically
+ * adds a space before @after_cmd_line, because it
+ * adds an additional device, not an attribute.
+ * - before node : added as additional argument to the node name.
+ * This argument is added optionally when creating edges,
+ * by setting the parameter @before_cmd_line in
+ * #QOSGraphEdgeOptions. This attribute
+ * is going to add attributes before the destination node
+ * pointed by the edge containing these options. It is
+ * helpful to commands that are not node-representable,
+ * such as "-fdsev" or "-netdev".
+ *
+ * While adding command line in edges is always used, not all nodes names are
+ * used in every path walk: this is because the contained or produced ones
+ * are already added by QEMU, so only nodes that "consumes" will be used to
+ * build the command line. Also, nodes that will have { "abstract" : true }
+ * as QMP attribute will loose their command line, since they are not proper
+ * devices to be added in QEMU.
+ *
+ * Example:
+ *
+ QOSGraphEdgeOptions opts = {
+ .arg = NULL,
+ .size_arg = 0,
+ .after_cmd_line = "-device other",
+ .before_cmd_line = "-netdev something",
+ .extra_edge_opts = "addr=04.0",
+ };
+ QOSGraphNode * node = qos_node_create_driver("my_node", constructor);
+ qos_node_consumes_args("my_node", "interface", &opts);
+ *
+ * Will produce the following command line:
+ * "-netdev something -device my_node,addr=04.0 -device other"
+ */
+
+/**
+ * Edge options to be passed to the contains/consumes *_args function.
+ */
+struct QOSGraphEdgeOptions {
+ void *arg; /*
+ * optional arg that will be used by
+ * dest edge
+ */
+ uint32_t size_arg; /*
+ * optional arg size that will be used by
+ * dest edge
+ */
+ const char *extra_device_opts;/*
+ *optional additional command line for dest
+ * edge, used to add additional attributes
+ * *after* the node command line, the
+ * framework automatically prepends ","
+ * to this argument.
+ */
+ const char *before_cmd_line; /*
+ * optional additional command line for dest
+ * edge, used to add additional attributes
+ * *before* the node command line, usually
+ * other non-node represented commands,
+ * like "-fdsev synt"
+ */
+ const char *after_cmd_line; /*
+ * optional extra command line to be added
+ * after the device command. This option
+ * is used to add other devices
+ * command line that depend on current node.
+ * Automatically prepends " " to this
+ * argument
+ */
+ const char *edge_name; /*
+ * optional edge to differentiate multiple
+ * devices with same node name
+ */
+};
+
+/**
+ * Test options to be passed to the test functions.
+ */
+struct QOSGraphTestOptions {
+ QOSGraphEdgeOptions edge; /* edge arguments that will be used by test.
+ * Note that test *does not* use edge_name,
+ * and uses instead arg and size_arg as
+ * data arg for its test function.
+ */
+ void *arg; /* passed to the .before function, or to the
+ * test function if there is no .before
+ * function
+ */
+ QOSBeforeTest before; /* executed before the test. Can add
+ * additional parameters to the command line
+ * and modify the argument to the test function.
+ */
+ bool subprocess; /* run the test in a subprocess */
+};
+
+/**
+ * Each driver, test or machine of this framework will have a
+ * QOSGraphObject as first field.
+ *
+ * This set of functions offered by QOSGraphObject are executed
+ * in different stages of the framework:
+ * - get_driver / get_device : Once a machine-to-test path has been
+ * found, the framework traverses it again and allocates all the
+ * nodes, using the provided constructor. To satisfy their relations,
+ * i.e. for produces or contains, where a struct constructor needs
+ * an external parameter represented by the previous node,
+ * the framework will call get_device (for contains) or
+ * get_driver (for produces), depending on the edge type, passing
+ * them the name of the next node to be taken and getting from them
+ * the corresponding pointer to the actual structure of the next node to
+ * be used in the path.
+ *
+ * - start_hw: This function is executed after all the path objects
+ * have been allocated, but before the test is run. It starts the hw, setting
+ * the initial configurations (*_device_enable) and making it ready for the
+ * test.
+ *
+ * - destructor: Opposite to the node constructor, destroys the object.
+ * This function is called after the test has been executed, and performs
+ * a complete cleanup of each node allocated field. In case no constructor
+ * is provided, no destructor will be called.
+ *
+ */
+struct QOSGraphObject {
+ /* for produces edges, returns void * */
+ QOSGetDriver get_driver;
+ /* for contains edges, returns a QOSGraphObject * */
+ QOSGetDevice get_device;
+ /* start the hw, get ready for the test */
+ QOSStartFunct start_hw;
+ /* destroy this QOSGraphObject */
+ QOSDestructorFunc destructor;
+ /* free the memory associated to the QOSGraphObject and its contained
+ * children */
+ GDestroyNotify free;
+};
+
+/**
+ * qos_graph_init(): initialize the framework, creates two hash
+ * tables: one for the nodes and another for the edges.
+ */
+void qos_graph_init(void);
+
+/**
+ * qos_graph_destroy(): deallocates all the hash tables,
+ * freeing all nodes and edges.
+ */
+void qos_graph_destroy(void);
+
+/**
+ * qos_node_destroy(): removes and frees a node from the,
+ * nodes hash table.
+ */
+void qos_node_destroy(void *key);
+
+/**
+ * qos_edge_destroy(): removes and frees an edge from the,
+ * edges hash table.
+ */
+void qos_edge_destroy(void *key);
+
+/**
+ * qos_add_test(): adds a test node @name to the nodes hash table.
+ *
+ * The test will consume a @interface node, and once the
+ * graph walking algorithm has found it, the @test_func will be
+ * executed. It also has the possibility to
+ * add an optional @opts (see %QOSGraphNodeOptions).
+ *
+ * For tests, opts->edge.arg and size_arg represent the arg to pass
+ * to @test_func
+ */
+void qos_add_test(const char *name, const char *interface,
+ QOSTestFunc test_func,
+ QOSGraphTestOptions *opts);
+
+/**
+ * qos_node_create_machine(): creates the machine @name and
+ * adds it to the node hash table.
+ *
+ * This node will be of type QNODE_MACHINE and have @function
+ * as constructor
+ */
+void qos_node_create_machine(const char *name, QOSCreateMachineFunc function);
+
+/**
+ * qos_node_create_machine_args(): same as qos_node_create_machine,
+ * but with the possibility to add an optional ", @opts" after -M machine
+ * command line.
+ */
+void qos_node_create_machine_args(const char *name,
+ QOSCreateMachineFunc function,
+ const char *opts);
+
+/**
+ * qos_node_create_driver(): creates the driver @name and
+ * adds it to the node hash table.
+ *
+ * This node will be of type QNODE_DRIVER and have @function
+ * as constructor
+ */
+void qos_node_create_driver(const char *name, QOSCreateDriverFunc function);
+
+/**
+ * qos_node_contains(): creates an edge of type QEDGE_CONTAINS and
+ * adds it to the edge list mapped to @container in the
+ * edge hash table.
+ *
+ * This edge will have @container as source and @contained as destination.
+ *
+ * It also has the possibility to add optional NULL-terminated
+ * @opts parameters (see %QOSGraphEdgeOptions)
+ *
+ * This function can be useful when there are multiple devices
+ * with the same node name contained in a machine/other node
+ *
+ * For example, if "arm/raspi2" contains 2 "generic-sdhci"
+ * devices, the right commands will be:
+ * qos_node_create_machine("arm/raspi2");
+ * qos_node_create_driver("generic-sdhci", constructor);
+ * //assume rest of the fields are set NULL
+ * QOSGraphEdgeOptions op1 = { .edge_name = "emmc" };
+ * QOSGraphEdgeOptions op2 = { .edge_name = "sdcard" };
+ * qos_node_contains("arm/raspi2", "generic-sdhci", &op1, &op2, NULL);
+ *
+ * Of course this also requires that the @container's get_device function
+ * should implement a case for "emmc" and "sdcard".
+ *
+ * For contains, op1.arg and op1.size_arg represent the arg to pass
+ * to @contained constructor to properly initialize it.
+ */
+void qos_node_contains(const char *container, const char *contained, ...);
+
+/**
+ * qos_node_produces(): creates an edge of type QEDGE_PRODUCES and
+ * adds it to the edge list mapped to @producer in the
+ * edge hash table.
+ *
+ * This edge will have @producer as source and @interface as destination.
+ */
+void qos_node_produces(const char *producer, const char *interface);
+
+/**
+ * qos_node_consumes(): creates an edge of type QEDGE_CONSUMED_BY and
+ * adds it to the edge list mapped to @interface in the
+ * edge hash table.
+ *
+ * This edge will have @interface as source and @consumer as destination.
+ * It also has the possibility to add an optional @opts
+ * (see %QOSGraphEdgeOptions)
+ */
+void qos_node_consumes(const char *consumer, const char *interface,
+ QOSGraphEdgeOptions *opts);
+
+/**
+ * qos_invalidate_command_line(): invalidates current command line, so that
+ * qgraph framework cannot try to cache the current command line and
+ * forces QEMU to restart.
+ */
+void qos_invalidate_command_line(void);
+
+/**
+ * qos_get_current_command_line(): return the command line required by the
+ * machine and driver objects. This is the same string that was passed to
+ * the test's "before" callback, if any.
+ */
+const char *qos_get_current_command_line(void);
+
+/**
+ * qos_allocate_objects():
+ * @qts: The #QTestState that will be referred to by the machine object.
+ * @alloc: Where to store the allocator for the machine object, or %NULL.
+ *
+ * Allocate driver objects for the current test
+ * path, but relative to the QTestState @qts.
+ *
+ * Returns a test object just like the one that was passed to
+ * the test function, but relative to @qts.
+ */
+void *qos_allocate_objects(QTestState *qts, QGuestAllocator **p_alloc);
+
+/**
+ * qos_object_destroy(): calls the destructor for @obj
+ */
+void qos_object_destroy(QOSGraphObject *obj);
+
+/**
+ * qos_object_queue_destroy(): queue the destructor for @obj so that it is
+ * called at the end of the test
+ */
+void qos_object_queue_destroy(QOSGraphObject *obj);
+
+/**
+ * qos_object_start_hw(): calls the start_hw function for @obj
+ */
+void qos_object_start_hw(QOSGraphObject *obj);
+
+/**
+ * qos_machine_new(): instantiate a new machine node
+ * @node: A machine node to be instantiated
+ * @qts: The #QTestState that will be referred to by the machine object.
+ *
+ * Returns a machine object.
+ */
+QOSGraphObject *qos_machine_new(QOSGraphNode *node, QTestState *qts);
+
+/**
+ * qos_machine_new(): instantiate a new driver node
+ * @node: A driver node to be instantiated
+ * @parent: A #QOSGraphObject to be consumed by the new driver node
+ * @alloc: An allocator to be used by the new driver node.
+ * @arg: The argument for the consumed-by edge to @node.
+ *
+ * Calls the constructor for the driver object.
+ */
+QOSGraphObject *qos_driver_new(QOSGraphNode *node, QOSGraphObject *parent,
+ QGuestAllocator *alloc, void *arg);
+
+
+#endif
diff --git a/tests/libqos/qgraph_internal.h b/tests/libqos/qgraph_internal.h
new file mode 100644
index 0000000000..2ef748baf6
--- /dev/null
+++ b/tests/libqos/qgraph_internal.h
@@ -0,0 +1,257 @@
+/*
+ * libqos driver framework
+ *
+ * Copyright (c) 2018 Emanuele Giuseppe Esposito <e.emanuelegiuseppe@gmail.com>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2 as published by the Free Software Foundation.
+ *
+ * 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 QGRAPH_EXTRA_H
+#define QGRAPH_EXTRA_H
+
+/* This header is declaring additional helper functions defined in
+ * libqos/qgraph.c
+ * It should not be included in tests
+ */
+
+#include "libqos/qgraph.h"
+
+typedef struct QOSGraphMachine QOSGraphMachine;
+typedef enum QOSEdgeType QOSEdgeType;
+typedef enum QOSNodeType QOSNodeType;
+
+/* callback called when the walk path algorithm found a
+ * valid path
+ */
+typedef void (*QOSTestCallback) (QOSGraphNode *path, int len);
+
+/* edge types*/
+enum QOSEdgeType {
+ QEDGE_CONTAINS,
+ QEDGE_PRODUCES,
+ QEDGE_CONSUMED_BY
+};
+
+/* node types*/
+enum QOSNodeType {
+ QNODE_MACHINE,
+ QNODE_DRIVER,
+ QNODE_INTERFACE,
+ QNODE_TEST
+};
+
+/* Graph Node */
+struct QOSGraphNode {
+ QOSNodeType type;
+ bool available; /* set by QEMU via QMP, used during graph walk */
+ bool visited; /* used during graph walk */
+ char *name; /* used to identify the node */
+ char *command_line; /* used to start QEMU at test execution */
+ union {
+ struct {
+ QOSCreateDriverFunc constructor;
+ } driver;
+ struct {
+ QOSCreateMachineFunc constructor;
+ } machine;
+ struct {
+ QOSTestFunc function;
+ void *arg;
+ QOSBeforeTest before;
+ bool subprocess;
+ } test;
+ } u;
+
+ /**
+ * only used when traversing the path, never rely on that except in the
+ * qos_traverse_graph callback function
+ */
+ QOSGraphEdge *path_edge;
+};
+
+/**
+ * qos_graph_get_node(): returns the node mapped to that @key.
+ * It performs an hash map search O(1)
+ *
+ * Returns: on success: the %QOSGraphNode
+ * otherwise: #NULL
+ */
+QOSGraphNode *qos_graph_get_node(const char *key);
+
+/**
+ * qos_graph_has_node(): returns #TRUE if the node
+ * has map has a node mapped to that @key.
+ */
+bool qos_graph_has_node(const char *node);
+
+/**
+ * qos_graph_get_node_type(): returns the %QOSNodeType
+ * of the node @node.
+ * It performs an hash map search O(1)
+ * Returns: on success: the %QOSNodeType
+ * otherwise: #-1
+ */
+QOSNodeType qos_graph_get_node_type(const char *node);
+
+/**
+ * qos_graph_get_node_availability(): returns the availability (boolean)
+ * of the node @node.
+ */
+bool qos_graph_get_node_availability(const char *node);
+
+/**
+ * qos_graph_get_edge(): returns the edge
+ * linking of the node @node with @dest.
+ *
+ * Returns: on success: the %QOSGraphEdge
+ * otherwise: #NULL
+ */
+QOSGraphEdge *qos_graph_get_edge(const char *node, const char *dest);
+
+/**
+ * qos_graph_edge_get_type(): returns the edge type
+ * of the edge @edge.
+ *
+ * Returns: on success: the %QOSEdgeType
+ * otherwise: #-1
+ */
+QOSEdgeType qos_graph_edge_get_type(QOSGraphEdge *edge);
+
+/**
+ * qos_graph_edge_get_dest(): returns the name of the node
+ * pointed as destination of edge @edge.
+ *
+ * Returns: on success: the destination
+ * otherwise: #NULL
+ */
+char *qos_graph_edge_get_dest(QOSGraphEdge *edge);
+
+/**
+ * qos_graph_has_edge(): returns #TRUE if there
+ * exists an edge from @start to @dest.
+ */
+bool qos_graph_has_edge(const char *start, const char *dest);
+
+/**
+ * qos_graph_edge_get_arg(): returns the args assigned
+ * to that @edge.
+ *
+ * Returns: on success: the arg
+ * otherwise: #NULL
+ */
+void *qos_graph_edge_get_arg(QOSGraphEdge *edge);
+
+/**
+ * qos_graph_edge_get_after_cmd_line(): returns the edge
+ * command line that will be added after all the node arguments
+ * and all the before_cmd_line arguments.
+ *
+ * Returns: on success: the char* arg
+ * otherwise: #NULL
+ */
+char *qos_graph_edge_get_after_cmd_line(QOSGraphEdge *edge);
+
+/**
+ * qos_graph_edge_get_before_cmd_line(): returns the edge
+ * command line that will be added before the node command
+ * line argument.
+ *
+ * Returns: on success: the char* arg
+ * otherwise: #NULL
+ */
+char *qos_graph_edge_get_before_cmd_line(QOSGraphEdge *edge);
+
+/**
+ * qos_graph_edge_get_extra_device_opts(): returns the arg
+ * command line that will be added to the node command
+ * line argument.
+ *
+ * Returns: on success: the char* arg
+ * otherwise: #NULL
+ */
+char *qos_graph_edge_get_extra_device_opts(QOSGraphEdge *edge);
+
+/**
+ * qos_graph_edge_get_name(): returns the name
+ * assigned to the destination node (different only)
+ * if there are multiple devices with the same node name
+ * e.g. a node has two "generic-sdhci", "emmc" and "sdcard"
+ * there will be two edges with edge_name ="emmc" and "sdcard"
+ *
+ * Returns always the char* edge_name
+ */
+char *qos_graph_edge_get_name(QOSGraphEdge *edge);
+
+/**
+ * qos_graph_get_machine(): returns the machine assigned
+ * to that @node name.
+ *
+ * It performs a search only trough the list of machines
+ * (i.e. the QOS_ROOT child).
+ *
+ * Returns: on success: the %QOSGraphNode
+ * otherwise: #NULL
+ */
+QOSGraphNode *qos_graph_get_machine(const char *node);
+
+/**
+ * qos_graph_has_machine(): returns #TRUE if the node
+ * has map has a node mapped to that @node.
+ */
+bool qos_graph_has_machine(const char *node);
+
+
+/**
+ * qos_print_graph(): walks the graph and prints
+ * all machine-to-test paths.
+ */
+void qos_print_graph(void);
+
+/**
+ * qos_graph_foreach_test_path(): executes the Depth First search
+ * algorithm and applies @fn to all discovered paths.
+ *
+ * See qos_traverse_graph() in qgraph.c for more info on
+ * how it works.
+ */
+void qos_graph_foreach_test_path(QOSTestCallback fn);
+
+/**
+ * qos_get_machine_type(): return QEMU machine type for a machine node.
+ * This function requires every machine @name to be in the form
+ * <arch>/<machine_name>, like "arm/raspi2" or "x86_64/pc".
+ *
+ * The function will validate the format and return a pointer to
+ * @machine to <machine_name>. For example, when passed "x86_64/pc"
+ * it will return "pc".
+ *
+ * Note that this function *does not* allocate any new string.
+ */
+char *qos_get_machine_type(char *name);
+
+/**
+ * qos_delete_cmd_line(): delete the
+ * command line present in node mapped with key @name.
+ *
+ * This function is called when the QMP query returns a node with
+ * { "abstract" : true } attribute.
+ */
+void qos_delete_cmd_line(const char *name);
+
+/**
+ * qos_graph_node_set_availability(): sets the node identified
+ * by @node with availability @av.
+ */
+void qos_graph_node_set_availability(const char *node, bool av);
+
+#endif
diff --git a/tests/libqos/sdhci.c b/tests/libqos/sdhci.c
new file mode 100644
index 0000000000..22c33de453
--- /dev/null
+++ b/tests/libqos/sdhci.c
@@ -0,0 +1,163 @@
+/*
+ * libqos driver framework
+ *
+ * Copyright (c) 2018 Emanuele Giuseppe Esposito <e.emanuelegiuseppe@gmail.com>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2 as published by the Free Software Foundation.
+ *
+ * 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 "libqos/qgraph.h"
+#include "pci.h"
+#include "sdhci.h"
+#include "hw/pci/pci.h"
+
+static void set_qsdhci_fields(QSDHCI *s, uint8_t version, uint8_t baseclock,
+ bool sdma, uint64_t reg)
+{
+ s->props.version = version;
+ s->props.baseclock = baseclock;
+ s->props.capab.sdma = sdma;
+ s->props.capab.reg = reg;
+}
+
+/* Memory mapped implementation of QSDHCI */
+
+static uint16_t sdhci_mm_readw(QSDHCI *s, uint32_t reg)
+{
+ QSDHCI_MemoryMapped *smm = container_of(s, QSDHCI_MemoryMapped, sdhci);
+ return qtest_readw(smm->qts, smm->addr + reg);
+}
+
+static uint64_t sdhci_mm_readq(QSDHCI *s, uint32_t reg)
+{
+ QSDHCI_MemoryMapped *smm = container_of(s, QSDHCI_MemoryMapped, sdhci);
+ return qtest_readq(smm->qts, smm->addr + reg);
+}
+
+static void sdhci_mm_writeq(QSDHCI *s, uint32_t reg, uint64_t val)
+{
+ QSDHCI_MemoryMapped *smm = container_of(s, QSDHCI_MemoryMapped, sdhci);
+ qtest_writeq(smm->qts, smm->addr + reg, val);
+}
+
+static void *sdhci_mm_get_driver(void *obj, const char *interface)
+{
+ QSDHCI_MemoryMapped *smm = obj;
+ if (!g_strcmp0(interface, "sdhci")) {
+ return &smm->sdhci;
+ }
+ fprintf(stderr, "%s not present in generic-sdhci\n", interface);
+ g_assert_not_reached();
+}
+
+void qos_init_sdhci_mm(QSDHCI_MemoryMapped *sdhci, QTestState *qts,
+ uint32_t addr, QSDHCIProperties *common)
+{
+ sdhci->obj.get_driver = sdhci_mm_get_driver;
+ sdhci->sdhci.readw = sdhci_mm_readw;
+ sdhci->sdhci.readq = sdhci_mm_readq;
+ sdhci->sdhci.writeq = sdhci_mm_writeq;
+ memcpy(&sdhci->sdhci.props, common, sizeof(QSDHCIProperties));
+ sdhci->addr = addr;
+ sdhci->qts = qts;
+}
+
+/* PCI implementation of QSDHCI */
+
+static uint16_t sdhci_pci_readw(QSDHCI *s, uint32_t reg)
+{
+ QSDHCI_PCI *spci = container_of(s, QSDHCI_PCI, sdhci);
+ return qpci_io_readw(&spci->dev, spci->mem_bar, reg);
+}
+
+static uint64_t sdhci_pci_readq(QSDHCI *s, uint32_t reg)
+{
+ QSDHCI_PCI *spci = container_of(s, QSDHCI_PCI, sdhci);
+ return qpci_io_readq(&spci->dev, spci->mem_bar, reg);
+}
+
+static void sdhci_pci_writeq(QSDHCI *s, uint32_t reg, uint64_t val)
+{
+ QSDHCI_PCI *spci = container_of(s, QSDHCI_PCI, sdhci);
+ return qpci_io_writeq(&spci->dev, spci->mem_bar, reg, val);
+}
+
+static void *sdhci_pci_get_driver(void *object, const char *interface)
+{
+ QSDHCI_PCI *spci = object;
+ if (!g_strcmp0(interface, "sdhci")) {
+ return &spci->sdhci;
+ }
+
+ fprintf(stderr, "%s not present in sdhci-pci\n", interface);
+ g_assert_not_reached();
+}
+
+static void sdhci_pci_start_hw(QOSGraphObject *obj)
+{
+ QSDHCI_PCI *spci = (QSDHCI_PCI *)obj;
+ qpci_device_enable(&spci->dev);
+}
+
+static void sdhci_destructor(QOSGraphObject *obj)
+{
+ QSDHCI_PCI *spci = (QSDHCI_PCI *)obj;
+ qpci_iounmap(&spci->dev, spci->mem_bar);
+}
+
+static void *sdhci_pci_create(void *pci_bus, QGuestAllocator *alloc, void *addr)
+{
+ QSDHCI_PCI *spci = g_new0(QSDHCI_PCI, 1);
+ QPCIBus *bus = pci_bus;
+ uint64_t barsize;
+
+ qpci_device_init(&spci->dev, bus, addr);
+ spci->mem_bar = qpci_iomap(&spci->dev, 0, &barsize);
+ spci->sdhci.readw = sdhci_pci_readw;
+ spci->sdhci.readq = sdhci_pci_readq;
+ spci->sdhci.writeq = sdhci_pci_writeq;
+ set_qsdhci_fields(&spci->sdhci, 2, 0, 1, 0x057834b4);
+
+ spci->obj.get_driver = sdhci_pci_get_driver;
+ spci->obj.start_hw = sdhci_pci_start_hw;
+ spci->obj.destructor = sdhci_destructor;
+ return &spci->obj;
+}
+
+static void qsdhci_register_nodes(void)
+{
+ QPCIAddress addr = {
+ .devfn = QPCI_DEVFN(4, 0),
+ .vendor_id = PCI_VENDOR_ID_REDHAT,
+ .device_id = PCI_DEVICE_ID_REDHAT_SDHCI,
+ };
+
+ QOSGraphEdgeOptions opts = {
+ .extra_device_opts = "addr=04.0",
+ };
+
+ /* generic-sdhci */
+ qos_node_create_driver("generic-sdhci", NULL);
+ qos_node_produces("generic-sdhci", "sdhci");
+
+ /* sdhci-pci */
+ add_qpci_address(&opts, &addr);
+ qos_node_create_driver("sdhci-pci", sdhci_pci_create);
+ qos_node_produces("sdhci-pci", "sdhci");
+ qos_node_consumes("sdhci-pci", "pci-bus", &opts);
+
+}
+
+libqos_init(qsdhci_register_nodes);
diff --git a/tests/libqos/sdhci.h b/tests/libqos/sdhci.h
new file mode 100644
index 0000000000..032d815c38
--- /dev/null
+++ b/tests/libqos/sdhci.h
@@ -0,0 +1,70 @@
+/*
+ * libqos driver framework
+ *
+ * Copyright (c) 2018 Emanuele Giuseppe Esposito <e.emanuelegiuseppe@gmail.com>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2 as published by the Free Software Foundation.
+ *
+ * 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 QGRAPH_QSDHCI
+#define QGRAPH_QSDHCI
+
+#include "libqos/qgraph.h"
+#include "pci.h"
+
+typedef struct QSDHCI QSDHCI;
+typedef struct QSDHCI_MemoryMapped QSDHCI_MemoryMapped;
+typedef struct QSDHCI_PCI QSDHCI_PCI;
+typedef struct QSDHCIProperties QSDHCIProperties;
+
+/* Properties common to all QSDHCI devices */
+struct QSDHCIProperties {
+ uint8_t version;
+ uint8_t baseclock;
+ struct {
+ bool sdma;
+ uint64_t reg;
+ } capab;
+};
+
+struct QSDHCI {
+ uint16_t (*readw)(QSDHCI *s, uint32_t reg);
+ uint64_t (*readq)(QSDHCI *s, uint32_t reg);
+ void (*writeq)(QSDHCI *s, uint32_t reg, uint64_t val);
+ QSDHCIProperties props;
+};
+
+/* Memory Mapped implementation of QSDHCI */
+struct QSDHCI_MemoryMapped {
+ QOSGraphObject obj;
+ QTestState *qts;
+ QSDHCI sdhci;
+ uint64_t addr;
+};
+
+/* PCI implementation of QSDHCI */
+struct QSDHCI_PCI {
+ QOSGraphObject obj;
+ QPCIDevice dev;
+ QSDHCI sdhci;
+ QPCIBar mem_bar;
+};
+
+/**
+ * qos_init_sdhci_mm(): external constructor used by all drivers/machines
+ * that "contain" a #QSDHCI_MemoryMapped driver
+ */
+void qos_init_sdhci_mm(QSDHCI_MemoryMapped *sdhci, QTestState *qts,
+ uint32_t addr, QSDHCIProperties *common);
+
+#endif
diff --git a/tests/libqos/tpci200.c b/tests/libqos/tpci200.c
new file mode 100644
index 0000000000..98dc532933
--- /dev/null
+++ b/tests/libqos/tpci200.c
@@ -0,0 +1,65 @@
+/*
+ * QTest testcase for tpci200 PCI-IndustryPack bridge
+ *
+ * Copyright (c) 2014 SUSE LINUX Products GmbH
+ *
+ * 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 "libqos/qgraph.h"
+#include "libqos/pci.h"
+
+typedef struct QTpci200 QTpci200;
+typedef struct QIpack QIpack;
+
+struct QIpack {
+
+};
+struct QTpci200 {
+ QOSGraphObject obj;
+ QPCIDevice dev;
+ QIpack ipack;
+};
+
+/* tpci200 */
+static void *tpci200_get_driver(void *obj, const char *interface)
+{
+ QTpci200 *tpci200 = obj;
+ if (!g_strcmp0(interface, "ipack")) {
+ return &tpci200->ipack;
+ }
+ if (!g_strcmp0(interface, "pci-device")) {
+ return &tpci200->dev;
+ }
+
+ fprintf(stderr, "%s not present in tpci200\n", interface);
+ g_assert_not_reached();
+}
+
+static void *tpci200_create(void *pci_bus, QGuestAllocator *alloc, void *addr)
+{
+ QTpci200 *tpci200 = g_new0(QTpci200, 1);
+ QPCIBus *bus = pci_bus;
+
+ qpci_device_init(&tpci200->dev, bus, addr);
+ tpci200->obj.get_driver = tpci200_get_driver;
+ return &tpci200->obj;
+}
+
+static void tpci200_register_nodes(void)
+{
+ QOSGraphEdgeOptions opts = {
+ .extra_device_opts = "addr=04.0,id=ipack0",
+ };
+ add_qpci_address(&opts, &(QPCIAddress) { .devfn = QPCI_DEVFN(4, 0) });
+
+ qos_node_create_driver("tpci200", tpci200_create);
+ qos_node_consumes("tpci200", "pci-bus", &opts);
+ qos_node_produces("tpci200", "ipack");
+ qos_node_produces("tpci200", "pci-device");
+}
+
+libqos_init(tpci200_register_nodes);
diff --git a/tests/libqos/virtio-9p.c b/tests/libqos/virtio-9p.c
new file mode 100644
index 0000000000..a378b56fa9
--- /dev/null
+++ b/tests/libqos/virtio-9p.c
@@ -0,0 +1,173 @@
+/*
+ * libqos driver framework
+ *
+ * Copyright (c) 2018 Emanuele Giuseppe Esposito <e.emanuelegiuseppe@gmail.com>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2 as published by the Free Software Foundation.
+ *
+ * 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 "standard-headers/linux/virtio_ids.h"
+#include "libqos/virtio-9p.h"
+#include "libqos/qgraph.h"
+
+static QGuestAllocator *alloc;
+
+static void virtio_9p_cleanup(QVirtio9P *interface)
+{
+ qvirtqueue_cleanup(interface->vdev->bus, interface->vq, alloc);
+}
+
+static void virtio_9p_setup(QVirtio9P *interface)
+{
+ interface->vq = qvirtqueue_setup(interface->vdev, alloc, 0);
+ qvirtio_set_driver_ok(interface->vdev);
+}
+
+/* virtio-9p-device */
+static void virtio_9p_device_destructor(QOSGraphObject *obj)
+{
+ QVirtio9PDevice *v_9p = (QVirtio9PDevice *) obj;
+ QVirtio9P *v9p = &v_9p->v9p;
+
+ virtio_9p_cleanup(v9p);
+}
+
+static void virtio_9p_device_start_hw(QOSGraphObject *obj)
+{
+ QVirtio9PDevice *v_9p = (QVirtio9PDevice *) obj;
+ QVirtio9P *v9p = &v_9p->v9p;
+
+ virtio_9p_setup(v9p);
+}
+
+static void *virtio_9p_get_driver(QVirtio9P *v_9p,
+ const char *interface)
+{
+ if (!g_strcmp0(interface, "virtio-9p")) {
+ return v_9p;
+ }
+ if (!g_strcmp0(interface, "virtio")) {
+ return v_9p->vdev;
+ }
+
+ fprintf(stderr, "%s not present in virtio-9p-device\n", interface);
+ g_assert_not_reached();
+}
+
+static void *virtio_9p_device_get_driver(void *object, const char *interface)
+{
+ QVirtio9PDevice *v_9p = object;
+ return virtio_9p_get_driver(&v_9p->v9p, interface);
+}
+
+static void *virtio_9p_device_create(void *virtio_dev,
+ QGuestAllocator *t_alloc,
+ void *addr)
+{
+ QVirtio9PDevice *virtio_device = g_new0(QVirtio9PDevice, 1);
+ QVirtio9P *interface = &virtio_device->v9p;
+
+ interface->vdev = virtio_dev;
+ alloc = t_alloc;
+
+ virtio_device->obj.destructor = virtio_9p_device_destructor;
+ virtio_device->obj.get_driver = virtio_9p_device_get_driver;
+ virtio_device->obj.start_hw = virtio_9p_device_start_hw;
+
+ return &virtio_device->obj;
+}
+
+/* virtio-9p-pci */
+static void virtio_9p_pci_destructor(QOSGraphObject *obj)
+{
+ QVirtio9PPCI *v9_pci = (QVirtio9PPCI *) obj;
+ QVirtio9P *interface = &v9_pci->v9p;
+ QOSGraphObject *pci_vobj = &v9_pci->pci_vdev.obj;
+
+ virtio_9p_cleanup(interface);
+ qvirtio_pci_destructor(pci_vobj);
+}
+
+static void virtio_9p_pci_start_hw(QOSGraphObject *obj)
+{
+ QVirtio9PPCI *v9_pci = (QVirtio9PPCI *) obj;
+ QVirtio9P *interface = &v9_pci->v9p;
+ QOSGraphObject *pci_vobj = &v9_pci->pci_vdev.obj;
+
+ qvirtio_pci_start_hw(pci_vobj);
+ virtio_9p_setup(interface);
+}
+
+static void *virtio_9p_pci_get_driver(void *object, const char *interface)
+{
+ QVirtio9PPCI *v_9p = object;
+ if (!g_strcmp0(interface, "pci-device")) {
+ return v_9p->pci_vdev.pdev;
+ }
+ return virtio_9p_get_driver(&v_9p->v9p, interface);
+}
+
+static void *virtio_9p_pci_create(void *pci_bus, QGuestAllocator *t_alloc,
+ void *addr)
+{
+ QVirtio9PPCI *v9_pci = g_new0(QVirtio9PPCI, 1);
+ QVirtio9P *interface = &v9_pci->v9p;
+ QOSGraphObject *obj = &v9_pci->pci_vdev.obj;
+
+ virtio_pci_init(&v9_pci->pci_vdev, pci_bus, addr);
+ interface->vdev = &v9_pci->pci_vdev.vdev;
+ alloc = t_alloc;
+
+ g_assert_cmphex(interface->vdev->device_type, ==, VIRTIO_ID_9P);
+
+ obj->destructor = virtio_9p_pci_destructor;
+ obj->start_hw = virtio_9p_pci_start_hw;
+ obj->get_driver = virtio_9p_pci_get_driver;
+
+ return obj;
+}
+
+static void virtio_9p_register_nodes(void)
+{
+ const char *str_simple = "fsdev=fsdev0,mount_tag=" MOUNT_TAG;
+ const char *str_addr = "fsdev=fsdev0,addr=04.0,mount_tag=" MOUNT_TAG;
+
+ QPCIAddress addr = {
+ .devfn = QPCI_DEVFN(4, 0),
+ };
+
+ QOSGraphEdgeOptions opts = {
+ .before_cmd_line = "-fsdev synth,id=fsdev0",
+ };
+
+ /* virtio-9p-device */
+ opts.extra_device_opts = str_simple,
+ qos_node_create_driver("virtio-9p-device", virtio_9p_device_create);
+ qos_node_consumes("virtio-9p-device", "virtio-bus", &opts);
+ qos_node_produces("virtio-9p-device", "virtio");
+ qos_node_produces("virtio-9p-device", "virtio-9p");
+
+ /* virtio-9p-pci */
+ opts.extra_device_opts = str_addr;
+ add_qpci_address(&opts, &addr);
+ qos_node_create_driver("virtio-9p-pci", virtio_9p_pci_create);
+ qos_node_consumes("virtio-9p-pci", "pci-bus", &opts);
+ qos_node_produces("virtio-9p-pci", "pci-device");
+ qos_node_produces("virtio-9p-pci", "virtio");
+ qos_node_produces("virtio-9p-pci", "virtio-9p");
+
+}
+
+libqos_init(virtio_9p_register_nodes);
diff --git a/tests/libqos/virtio-9p.h b/tests/libqos/virtio-9p.h
new file mode 100644
index 0000000000..dba22772b5
--- /dev/null
+++ b/tests/libqos/virtio-9p.h
@@ -0,0 +1,42 @@
+/*
+ * libqos driver framework
+ *
+ * Copyright (c) 2018 Emanuele Giuseppe Esposito <e.emanuelegiuseppe@gmail.com>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2 as published by the Free Software Foundation.
+ *
+ * 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 "libqos/qgraph.h"
+#include "libqos/virtio.h"
+#include "libqos/virtio-pci.h"
+
+typedef struct QVirtio9P QVirtio9P;
+typedef struct QVirtio9PPCI QVirtio9PPCI;
+typedef struct QVirtio9PDevice QVirtio9PDevice;
+
+#define MOUNT_TAG "qtest"
+
+struct QVirtio9P {
+ QVirtioDevice *vdev;
+ QVirtQueue *vq;
+};
+
+struct QVirtio9PPCI {
+ QVirtioPCIDevice pci_vdev;
+ QVirtio9P v9p;
+};
+
+struct QVirtio9PDevice {
+ QOSGraphObject obj;
+ QVirtio9P v9p;
+};
diff --git a/tests/libqos/virtio-balloon.c b/tests/libqos/virtio-balloon.c
new file mode 100644
index 0000000000..7e6e9e9de5
--- /dev/null
+++ b/tests/libqos/virtio-balloon.c
@@ -0,0 +1,113 @@
+/*
+ * libqos driver framework
+ *
+ * Copyright (c) 2018 Emanuele Giuseppe Esposito <e.emanuelegiuseppe@gmail.com>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2 as published by the Free Software Foundation.
+ *
+ * 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 "libqos/qgraph.h"
+#include "libqos/virtio-balloon.h"
+
+/* virtio-balloon-device */
+static void *qvirtio_balloon_get_driver(QVirtioBalloon *v_balloon,
+ const char *interface)
+{
+ if (!g_strcmp0(interface, "virtio-balloon")) {
+ return v_balloon;
+ }
+ if (!g_strcmp0(interface, "virtio")) {
+ return v_balloon->vdev;
+ }
+
+ fprintf(stderr, "%s not present in virtio-balloon-device\n", interface);
+ g_assert_not_reached();
+}
+
+static void *qvirtio_balloon_device_get_driver(void *object,
+ const char *interface)
+{
+ QVirtioBalloonDevice *v_balloon = object;
+ return qvirtio_balloon_get_driver(&v_balloon->balloon, interface);
+}
+
+static void *virtio_balloon_device_create(void *virtio_dev,
+ QGuestAllocator *t_alloc,
+ void *addr)
+{
+ QVirtioBalloonDevice *virtio_bdevice = g_new0(QVirtioBalloonDevice, 1);
+ QVirtioBalloon *interface = &virtio_bdevice->balloon;
+
+ interface->vdev = virtio_dev;
+
+ virtio_bdevice->obj.get_driver = qvirtio_balloon_device_get_driver;
+
+ return &virtio_bdevice->obj;
+}
+
+/* virtio-balloon-pci */
+static void *qvirtio_balloon_pci_get_driver(void *object,
+ const char *interface)
+{
+ QVirtioBalloonPCI *v_balloon = object;
+ if (!g_strcmp0(interface, "pci-device")) {
+ return v_balloon->pci_vdev.pdev;
+ }
+ return qvirtio_balloon_get_driver(&v_balloon->balloon, interface);
+}
+
+static void *virtio_balloon_pci_create(void *pci_bus, QGuestAllocator *t_alloc,
+ void *addr)
+{
+ QVirtioBalloonPCI *virtio_bpci = g_new0(QVirtioBalloonPCI, 1);
+ QVirtioBalloon *interface = &virtio_bpci->balloon;
+ QOSGraphObject *obj = &virtio_bpci->pci_vdev.obj;
+
+
+ virtio_pci_init(&virtio_bpci->pci_vdev, pci_bus, addr);
+ interface->vdev = &virtio_bpci->pci_vdev.vdev;
+
+ obj->get_driver = qvirtio_balloon_pci_get_driver;
+
+ return obj;
+}
+
+static void virtio_balloon_register_nodes(void)
+{
+ QPCIAddress addr = {
+ .devfn = QPCI_DEVFN(4, 0),
+ };
+
+ QOSGraphEdgeOptions opts = {
+ .extra_device_opts = "addr=04.0",
+ };
+
+ /* virtio-balloon-device */
+ qos_node_create_driver("virtio-balloon-device",
+ virtio_balloon_device_create);
+ qos_node_consumes("virtio-balloon-device", "virtio-bus", NULL);
+ qos_node_produces("virtio-balloon-device", "virtio");
+ qos_node_produces("virtio-balloon-device", "virtio-balloon");
+
+ /* virtio-balloon-pci */
+ add_qpci_address(&opts, &addr);
+ qos_node_create_driver("virtio-balloon-pci", virtio_balloon_pci_create);
+ qos_node_consumes("virtio-balloon-pci", "pci-bus", &opts);
+ qos_node_produces("virtio-balloon-pci", "pci-device");
+ qos_node_produces("virtio-balloon-pci", "virtio");
+ qos_node_produces("virtio-balloon-pci", "virtio-balloon");
+}
+
+libqos_init(virtio_balloon_register_nodes);
diff --git a/tests/libqos/virtio-balloon.h b/tests/libqos/virtio-balloon.h
new file mode 100644
index 0000000000..e8066c42bb
--- /dev/null
+++ b/tests/libqos/virtio-balloon.h
@@ -0,0 +1,39 @@
+/*
+ * libqos driver framework
+ *
+ * Copyright (c) 2018 Emanuele Giuseppe Esposito <e.emanuelegiuseppe@gmail.com>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2 as published by the Free Software Foundation.
+ *
+ * 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 "libqos/qgraph.h"
+#include "libqos/virtio.h"
+#include "libqos/virtio-pci.h"
+
+typedef struct QVirtioBalloon QVirtioBalloon;
+typedef struct QVirtioBalloonPCI QVirtioBalloonPCI;
+typedef struct QVirtioBalloonDevice QVirtioBalloonDevice;
+
+struct QVirtioBalloon {
+ QVirtioDevice *vdev;
+};
+
+struct QVirtioBalloonPCI {
+ QVirtioPCIDevice pci_vdev;
+ QVirtioBalloon balloon;
+};
+
+struct QVirtioBalloonDevice {
+ QOSGraphObject obj;
+ QVirtioBalloon balloon;
+};
diff --git a/tests/libqos/virtio-blk.c b/tests/libqos/virtio-blk.c
new file mode 100644
index 0000000000..c17bdf4217
--- /dev/null
+++ b/tests/libqos/virtio-blk.c
@@ -0,0 +1,124 @@
+/*
+ * libqos driver framework
+ *
+ * Copyright (c) 2018 Emanuele Giuseppe Esposito <e.emanuelegiuseppe@gmail.com>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2 as published by the Free Software Foundation.
+ *
+ * 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 "standard-headers/linux/virtio_blk.h"
+#include "libqos/qgraph.h"
+#include "libqos/virtio-blk.h"
+
+#define PCI_SLOT 0x04
+#define PCI_FN 0x00
+
+/* virtio-blk-device */
+static void *qvirtio_blk_get_driver(QVirtioBlk *v_blk,
+ const char *interface)
+{
+ if (!g_strcmp0(interface, "virtio-blk")) {
+ return v_blk;
+ }
+ if (!g_strcmp0(interface, "virtio")) {
+ return v_blk->vdev;
+ }
+
+ fprintf(stderr, "%s not present in virtio-blk-device\n", interface);
+ g_assert_not_reached();
+}
+
+static void *qvirtio_blk_device_get_driver(void *object,
+ const char *interface)
+{
+ QVirtioBlkDevice *v_blk = object;
+ return qvirtio_blk_get_driver(&v_blk->blk, interface);
+}
+
+static void *virtio_blk_device_create(void *virtio_dev,
+ QGuestAllocator *t_alloc,
+ void *addr)
+{
+ QVirtioBlkDevice *virtio_blk = g_new0(QVirtioBlkDevice, 1);
+ QVirtioBlk *interface = &virtio_blk->blk;
+
+ interface->vdev = virtio_dev;
+
+ virtio_blk->obj.get_driver = qvirtio_blk_device_get_driver;
+
+ return &virtio_blk->obj;
+}
+
+/* virtio-blk-pci */
+static void *qvirtio_blk_pci_get_driver(void *object, const char *interface)
+{
+ QVirtioBlkPCI *v_blk = object;
+ if (!g_strcmp0(interface, "pci-device")) {
+ return v_blk->pci_vdev.pdev;
+ }
+ return qvirtio_blk_get_driver(&v_blk->blk, interface);
+}
+
+static void *virtio_blk_pci_create(void *pci_bus, QGuestAllocator *t_alloc,
+ void *addr)
+{
+ QVirtioBlkPCI *virtio_blk = g_new0(QVirtioBlkPCI, 1);
+ QVirtioBlk *interface = &virtio_blk->blk;
+ QOSGraphObject *obj = &virtio_blk->pci_vdev.obj;
+
+ virtio_pci_init(&virtio_blk->pci_vdev, pci_bus, addr);
+ interface->vdev = &virtio_blk->pci_vdev.vdev;
+
+ g_assert_cmphex(interface->vdev->device_type, ==, VIRTIO_ID_BLOCK);
+
+ obj->get_driver = qvirtio_blk_pci_get_driver;
+
+ return obj;
+}
+
+static void virtio_blk_register_nodes(void)
+{
+ /* FIXME: every test using these two nodes needs to setup a
+ * -drive,id=drive0 otherwise QEMU is not going to start.
+ * Therefore, we do not include "produces" edge for virtio
+ * and pci-device yet.
+ */
+
+ char *arg = g_strdup_printf("id=drv0,drive=drive0,addr=%x.%x",
+ PCI_SLOT, PCI_FN);
+
+ QPCIAddress addr = {
+ .devfn = QPCI_DEVFN(PCI_SLOT, PCI_FN),
+ };
+
+ QOSGraphEdgeOptions opts = { };
+
+ /* virtio-blk-device */
+ opts.extra_device_opts = "drive=drive0";
+ qos_node_create_driver("virtio-blk-device", virtio_blk_device_create);
+ qos_node_consumes("virtio-blk-device", "virtio-bus", &opts);
+ qos_node_produces("virtio-blk-device", "virtio-blk");
+
+ /* virtio-blk-pci */
+ opts.extra_device_opts = arg;
+ add_qpci_address(&opts, &addr);
+ qos_node_create_driver("virtio-blk-pci", virtio_blk_pci_create);
+ qos_node_consumes("virtio-blk-pci", "pci-bus", &opts);
+ qos_node_produces("virtio-blk-pci", "virtio-blk");
+
+ g_free(arg);
+}
+
+libqos_init(virtio_blk_register_nodes);
diff --git a/tests/libqos/virtio-blk.h b/tests/libqos/virtio-blk.h
new file mode 100644
index 0000000000..dc258496ba
--- /dev/null
+++ b/tests/libqos/virtio-blk.h
@@ -0,0 +1,40 @@
+/*
+ * libqos driver framework
+ *
+ * Copyright (c) 2018 Emanuele Giuseppe Esposito <e.emanuelegiuseppe@gmail.com>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2 as published by the Free Software Foundation.
+ *
+ * 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 "libqos/qgraph.h"
+#include "libqos/virtio.h"
+#include "libqos/virtio-pci.h"
+
+typedef struct QVirtioBlk QVirtioBlk;
+typedef struct QVirtioBlkPCI QVirtioBlkPCI;
+typedef struct QVirtioBlkDevice QVirtioBlkDevice;
+
+/* virtqueue is created in each test */
+struct QVirtioBlk {
+ QVirtioDevice *vdev;
+};
+
+struct QVirtioBlkPCI {
+ QVirtioPCIDevice pci_vdev;
+ QVirtioBlk blk;
+};
+
+struct QVirtioBlkDevice {
+ QOSGraphObject obj;
+ QVirtioBlk blk;
+};
diff --git a/tests/libqos/virtio-mmio.c b/tests/libqos/virtio-mmio.c
index 7aa8383338..3678c07ef0 100644
--- a/tests/libqos/virtio-mmio.c
+++ b/tests/libqos/virtio-mmio.c
@@ -12,74 +12,74 @@
#include "libqos/virtio.h"
#include "libqos/virtio-mmio.h"
#include "libqos/malloc.h"
-#include "libqos/malloc-generic.h"
+#include "libqos/qgraph.h"
#include "standard-headers/linux/virtio_ring.h"
static uint8_t qvirtio_mmio_config_readb(QVirtioDevice *d, uint64_t off)
{
- QVirtioMMIODevice *dev = (QVirtioMMIODevice *)d;
- return readb(dev->addr + QVIRTIO_MMIO_DEVICE_SPECIFIC + off);
+ QVirtioMMIODevice *dev = container_of(d, QVirtioMMIODevice, vdev);
+ return qtest_readb(dev->qts, dev->addr + QVIRTIO_MMIO_DEVICE_SPECIFIC + off);
}
static uint16_t qvirtio_mmio_config_readw(QVirtioDevice *d, uint64_t off)
{
- QVirtioMMIODevice *dev = (QVirtioMMIODevice *)d;
- return readw(dev->addr + QVIRTIO_MMIO_DEVICE_SPECIFIC + off);
+ QVirtioMMIODevice *dev = container_of(d, QVirtioMMIODevice, vdev);
+ return qtest_readw(dev->qts, dev->addr + QVIRTIO_MMIO_DEVICE_SPECIFIC + off);
}
static uint32_t qvirtio_mmio_config_readl(QVirtioDevice *d, uint64_t off)
{
- QVirtioMMIODevice *dev = (QVirtioMMIODevice *)d;
- return readl(dev->addr + QVIRTIO_MMIO_DEVICE_SPECIFIC + off);
+ QVirtioMMIODevice *dev = container_of(d, QVirtioMMIODevice, vdev);
+ return qtest_readl(dev->qts, dev->addr + QVIRTIO_MMIO_DEVICE_SPECIFIC + off);
}
static uint64_t qvirtio_mmio_config_readq(QVirtioDevice *d, uint64_t off)
{
- QVirtioMMIODevice *dev = (QVirtioMMIODevice *)d;
- return readq(dev->addr + QVIRTIO_MMIO_DEVICE_SPECIFIC + off);
+ QVirtioMMIODevice *dev = container_of(d, QVirtioMMIODevice, vdev);
+ return qtest_readq(dev->qts, dev->addr + QVIRTIO_MMIO_DEVICE_SPECIFIC + off);
}
static uint32_t qvirtio_mmio_get_features(QVirtioDevice *d)
{
- QVirtioMMIODevice *dev = (QVirtioMMIODevice *)d;
- writel(dev->addr + QVIRTIO_MMIO_HOST_FEATURES_SEL, 0);
- return readl(dev->addr + QVIRTIO_MMIO_HOST_FEATURES);
+ QVirtioMMIODevice *dev = container_of(d, QVirtioMMIODevice, vdev);
+ qtest_writel(dev->qts, dev->addr + QVIRTIO_MMIO_HOST_FEATURES_SEL, 0);
+ return qtest_readl(dev->qts, dev->addr + QVIRTIO_MMIO_HOST_FEATURES);
}
static void qvirtio_mmio_set_features(QVirtioDevice *d, uint32_t features)
{
- QVirtioMMIODevice *dev = (QVirtioMMIODevice *)d;
+ QVirtioMMIODevice *dev = container_of(d, QVirtioMMIODevice, vdev);
dev->features = features;
- writel(dev->addr + QVIRTIO_MMIO_GUEST_FEATURES_SEL, 0);
- writel(dev->addr + QVIRTIO_MMIO_GUEST_FEATURES, features);
+ qtest_writel(dev->qts, dev->addr + QVIRTIO_MMIO_GUEST_FEATURES_SEL, 0);
+ qtest_writel(dev->qts, dev->addr + QVIRTIO_MMIO_GUEST_FEATURES, features);
}
static uint32_t qvirtio_mmio_get_guest_features(QVirtioDevice *d)
{
- QVirtioMMIODevice *dev = (QVirtioMMIODevice *)d;
+ QVirtioMMIODevice *dev = container_of(d, QVirtioMMIODevice, vdev);
return dev->features;
}
static uint8_t qvirtio_mmio_get_status(QVirtioDevice *d)
{
- QVirtioMMIODevice *dev = (QVirtioMMIODevice *)d;
- return (uint8_t)readl(dev->addr + QVIRTIO_MMIO_DEVICE_STATUS);
+ QVirtioMMIODevice *dev = container_of(d, QVirtioMMIODevice, vdev);
+ return (uint8_t)qtest_readl(dev->qts, dev->addr + QVIRTIO_MMIO_DEVICE_STATUS);
}
static void qvirtio_mmio_set_status(QVirtioDevice *d, uint8_t status)
{
- QVirtioMMIODevice *dev = (QVirtioMMIODevice *)d;
- writel(dev->addr + QVIRTIO_MMIO_DEVICE_STATUS, (uint32_t)status);
+ QVirtioMMIODevice *dev = container_of(d, QVirtioMMIODevice, vdev);
+ qtest_writel(dev->qts, dev->addr + QVIRTIO_MMIO_DEVICE_STATUS, (uint32_t)status);
}
static bool qvirtio_mmio_get_queue_isr_status(QVirtioDevice *d, QVirtQueue *vq)
{
- QVirtioMMIODevice *dev = (QVirtioMMIODevice *)d;
+ QVirtioMMIODevice *dev = container_of(d, QVirtioMMIODevice, vdev);
uint32_t isr;
- isr = readl(dev->addr + QVIRTIO_MMIO_INTERRUPT_STATUS) & 1;
+ isr = qtest_readl(dev->qts, dev->addr + QVIRTIO_MMIO_INTERRUPT_STATUS) & 1;
if (isr != 0) {
- writel(dev->addr + QVIRTIO_MMIO_INTERRUPT_ACK, 1);
+ qtest_writel(dev->qts, dev->addr + QVIRTIO_MMIO_INTERRUPT_ACK, 1);
return true;
}
@@ -88,12 +88,12 @@ static bool qvirtio_mmio_get_queue_isr_status(QVirtioDevice *d, QVirtQueue *vq)
static bool qvirtio_mmio_get_config_isr_status(QVirtioDevice *d)
{
- QVirtioMMIODevice *dev = (QVirtioMMIODevice *)d;
+ QVirtioMMIODevice *dev = container_of(d, QVirtioMMIODevice, vdev);
uint32_t isr;
- isr = readl(dev->addr + QVIRTIO_MMIO_INTERRUPT_STATUS) & 2;
+ isr = qtest_readl(dev->qts, dev->addr + QVIRTIO_MMIO_INTERRUPT_STATUS) & 2;
if (isr != 0) {
- writel(dev->addr + QVIRTIO_MMIO_INTERRUPT_ACK, 2);
+ qtest_writel(dev->qts, dev->addr + QVIRTIO_MMIO_INTERRUPT_ACK, 2);
return true;
}
@@ -102,34 +102,34 @@ static bool qvirtio_mmio_get_config_isr_status(QVirtioDevice *d)
static void qvirtio_mmio_queue_select(QVirtioDevice *d, uint16_t index)
{
- QVirtioMMIODevice *dev = (QVirtioMMIODevice *)d;
- writel(dev->addr + QVIRTIO_MMIO_QUEUE_SEL, (uint32_t)index);
+ QVirtioMMIODevice *dev = container_of(d, QVirtioMMIODevice, vdev);
+ qtest_writel(dev->qts, dev->addr + QVIRTIO_MMIO_QUEUE_SEL, (uint32_t)index);
- g_assert_cmphex(readl(dev->addr + QVIRTIO_MMIO_QUEUE_PFN), ==, 0);
+ g_assert_cmphex(qtest_readl(dev->qts, dev->addr + QVIRTIO_MMIO_QUEUE_PFN), ==, 0);
}
static uint16_t qvirtio_mmio_get_queue_size(QVirtioDevice *d)
{
- QVirtioMMIODevice *dev = (QVirtioMMIODevice *)d;
- return (uint16_t)readl(dev->addr + QVIRTIO_MMIO_QUEUE_NUM_MAX);
+ QVirtioMMIODevice *dev = container_of(d, QVirtioMMIODevice, vdev);
+ return (uint16_t)qtest_readl(dev->qts, dev->addr + QVIRTIO_MMIO_QUEUE_NUM_MAX);
}
static void qvirtio_mmio_set_queue_address(QVirtioDevice *d, uint32_t pfn)
{
- QVirtioMMIODevice *dev = (QVirtioMMIODevice *)d;
- writel(dev->addr + QVIRTIO_MMIO_QUEUE_PFN, pfn);
+ QVirtioMMIODevice *dev = container_of(d, QVirtioMMIODevice, vdev);
+ qtest_writel(dev->qts, dev->addr + QVIRTIO_MMIO_QUEUE_PFN, pfn);
}
static QVirtQueue *qvirtio_mmio_virtqueue_setup(QVirtioDevice *d,
QGuestAllocator *alloc, uint16_t index)
{
- QVirtioMMIODevice *dev = (QVirtioMMIODevice *)d;
+ QVirtioMMIODevice *dev = container_of(d, QVirtioMMIODevice, vdev);
QVirtQueue *vq;
uint64_t addr;
vq = g_malloc0(sizeof(*vq));
qvirtio_mmio_queue_select(d, index);
- writel(dev->addr + QVIRTIO_MMIO_QUEUE_ALIGN, dev->page_size);
+ qtest_writel(dev->qts, dev->addr + QVIRTIO_MMIO_QUEUE_ALIGN, dev->page_size);
vq->index = index;
vq->size = qvirtio_mmio_get_queue_size(d);
@@ -139,7 +139,7 @@ static QVirtQueue *qvirtio_mmio_virtqueue_setup(QVirtioDevice *d,
vq->indirect = (dev->features & (1u << VIRTIO_RING_F_INDIRECT_DESC)) != 0;
vq->event = (dev->features & (1u << VIRTIO_RING_F_EVENT_IDX)) != 0;
- writel(dev->addr + QVIRTIO_MMIO_QUEUE_NUM, vq->size);
+ qtest_writel(dev->qts, dev->addr + QVIRTIO_MMIO_QUEUE_NUM, vq->size);
/* Check different than 0 */
g_assert_cmpint(vq->size, !=, 0);
@@ -163,8 +163,8 @@ static void qvirtio_mmio_virtqueue_cleanup(QVirtQueue *vq,
static void qvirtio_mmio_virtqueue_kick(QVirtioDevice *d, QVirtQueue *vq)
{
- QVirtioMMIODevice *dev = (QVirtioMMIODevice *)d;
- writel(dev->addr + QVIRTIO_MMIO_QUEUE_NOTIFY, vq->index);
+ QVirtioMMIODevice *dev = container_of(d, QVirtioMMIODevice, vdev);
+ qtest_writel(dev->qts, dev->addr + QVIRTIO_MMIO_QUEUE_NOTIFY, vq->index);
}
const QVirtioBus qvirtio_mmio = {
@@ -187,21 +187,45 @@ const QVirtioBus qvirtio_mmio = {
.virtqueue_kick = qvirtio_mmio_virtqueue_kick,
};
-QVirtioMMIODevice *qvirtio_mmio_init_device(uint64_t addr, uint32_t page_size)
+static void *qvirtio_mmio_get_driver(void *obj, const char *interface)
{
- QVirtioMMIODevice *dev;
- uint32_t magic;
- dev = g_malloc0(sizeof(*dev));
+ QVirtioMMIODevice *virtio_mmio = obj;
+ if (!g_strcmp0(interface, "virtio-bus")) {
+ return &virtio_mmio->vdev;
+ }
+ fprintf(stderr, "%s not present in virtio-mmio\n", interface);
+ g_assert_not_reached();
+}
+
+static void qvirtio_mmio_start_hw(QOSGraphObject *obj)
+{
+ QVirtioMMIODevice *dev = (QVirtioMMIODevice *) obj;
+ qvirtio_start_device(&dev->vdev);
+}
- magic = readl(addr + QVIRTIO_MMIO_MAGIC_VALUE);
+void qvirtio_mmio_init_device(QVirtioMMIODevice *dev, QTestState *qts,
+ uint64_t addr, uint32_t page_size)
+{
+ uint32_t magic;
+ magic = qtest_readl(qts, addr + QVIRTIO_MMIO_MAGIC_VALUE);
g_assert(magic == ('v' | 'i' << 8 | 'r' << 16 | 't' << 24));
+ dev->qts = qts;
dev->addr = addr;
dev->page_size = page_size;
- dev->vdev.device_type = readl(addr + QVIRTIO_MMIO_DEVICE_ID);
+ dev->vdev.device_type = qtest_readl(qts, addr + QVIRTIO_MMIO_DEVICE_ID);
dev->vdev.bus = &qvirtio_mmio;
- writel(addr + QVIRTIO_MMIO_GUEST_PAGE_SIZE, page_size);
+ qtest_writel(qts, addr + QVIRTIO_MMIO_GUEST_PAGE_SIZE, page_size);
+
+ dev->obj.get_driver = qvirtio_mmio_get_driver;
+ dev->obj.start_hw = qvirtio_mmio_start_hw;
+}
- return dev;
+static void virtio_mmio_register_nodes(void)
+{
+ qos_node_create_driver("virtio-mmio", NULL);
+ qos_node_produces("virtio-mmio", "virtio-bus");
}
+
+libqos_init(virtio_mmio_register_nodes);
diff --git a/tests/libqos/virtio-mmio.h b/tests/libqos/virtio-mmio.h
index e3e52b9ce1..17a17141c3 100644
--- a/tests/libqos/virtio-mmio.h
+++ b/tests/libqos/virtio-mmio.h
@@ -11,6 +11,7 @@
#define LIBQOS_VIRTIO_MMIO_H
#include "libqos/virtio.h"
+#include "libqos/qgraph.h"
#define QVIRTIO_MMIO_MAGIC_VALUE 0x000
#define QVIRTIO_MMIO_VERSION 0x004
@@ -33,7 +34,9 @@
#define QVIRTIO_MMIO_DEVICE_SPECIFIC 0x100
typedef struct QVirtioMMIODevice {
+ QOSGraphObject obj;
QVirtioDevice vdev;
+ QTestState *qts;
uint64_t addr;
uint32_t page_size;
uint32_t features; /* As it cannot be read later, save it */
@@ -41,6 +44,7 @@ typedef struct QVirtioMMIODevice {
extern const QVirtioBus qvirtio_mmio;
-QVirtioMMIODevice *qvirtio_mmio_init_device(uint64_t addr, uint32_t page_size);
+void qvirtio_mmio_init_device(QVirtioMMIODevice *dev, QTestState *qts,
+ uint64_t addr, uint32_t page_size);
#endif
diff --git a/tests/libqos/virtio-net.c b/tests/libqos/virtio-net.c
new file mode 100644
index 0000000000..61c56170e9
--- /dev/null
+++ b/tests/libqos/virtio-net.c
@@ -0,0 +1,195 @@
+/*
+ * libqos driver framework
+ *
+ * Copyright (c) 2018 Emanuele Giuseppe Esposito <e.emanuelegiuseppe@gmail.com>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2 as published by the Free Software Foundation.
+ *
+ * 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 "libqos/qgraph.h"
+#include "libqos/virtio-net.h"
+#include "hw/virtio/virtio-net.h"
+
+
+static QGuestAllocator *alloc;
+
+static void virtio_net_cleanup(QVirtioNet *interface)
+{
+ int i;
+
+ for (i = 0; i < interface->n_queues; i++) {
+ qvirtqueue_cleanup(interface->vdev->bus, interface->queues[i], alloc);
+ }
+ g_free(interface->queues);
+}
+
+static void virtio_net_setup(QVirtioNet *interface)
+{
+ QVirtioDevice *vdev = interface->vdev;
+ uint64_t features;
+ int i;
+
+ features = qvirtio_get_features(vdev);
+ features &= ~(QVIRTIO_F_BAD_FEATURE |
+ (1u << VIRTIO_RING_F_INDIRECT_DESC) |
+ (1u << VIRTIO_RING_F_EVENT_IDX));
+ qvirtio_set_features(vdev, features);
+
+ if (features & (1u << VIRTIO_NET_F_MQ)) {
+ interface->n_queues = qvirtio_config_readw(vdev, 8) * 2;
+ } else {
+ interface->n_queues = 2;
+ }
+
+ interface->queues = g_new(QVirtQueue *, interface->n_queues);
+ for (i = 0; i < interface->n_queues; i++) {
+ interface->queues[i] = qvirtqueue_setup(vdev, alloc, i);
+ }
+ qvirtio_set_driver_ok(vdev);
+}
+
+/* virtio-net-device */
+static void qvirtio_net_device_destructor(QOSGraphObject *obj)
+{
+ QVirtioNetDevice *v_net = (QVirtioNetDevice *) obj;
+ virtio_net_cleanup(&v_net->net);
+}
+
+static void qvirtio_net_device_start_hw(QOSGraphObject *obj)
+{
+ QVirtioNetDevice *v_net = (QVirtioNetDevice *) obj;
+ QVirtioNet *interface = &v_net->net;
+
+ virtio_net_setup(interface);
+}
+
+static void *qvirtio_net_get_driver(QVirtioNet *v_net,
+ const char *interface)
+{
+ if (!g_strcmp0(interface, "virtio-net")) {
+ return v_net;
+ }
+ if (!g_strcmp0(interface, "virtio")) {
+ return v_net->vdev;
+ }
+
+ fprintf(stderr, "%s not present in virtio-net-device\n", interface);
+ g_assert_not_reached();
+}
+
+static void *qvirtio_net_device_get_driver(void *object,
+ const char *interface)
+{
+ QVirtioNetDevice *v_net = object;
+ return qvirtio_net_get_driver(&v_net->net, interface);
+}
+
+static void *virtio_net_device_create(void *virtio_dev,
+ QGuestAllocator *t_alloc,
+ void *addr)
+{
+ QVirtioNetDevice *virtio_ndevice = g_new0(QVirtioNetDevice, 1);
+ QVirtioNet *interface = &virtio_ndevice->net;
+
+ interface->vdev = virtio_dev;
+ alloc = t_alloc;
+
+ virtio_ndevice->obj.destructor = qvirtio_net_device_destructor;
+ virtio_ndevice->obj.get_driver = qvirtio_net_device_get_driver;
+ virtio_ndevice->obj.start_hw = qvirtio_net_device_start_hw;
+
+ return &virtio_ndevice->obj;
+}
+
+/* virtio-net-pci */
+static void qvirtio_net_pci_destructor(QOSGraphObject *obj)
+{
+ QVirtioNetPCI *v_net = (QVirtioNetPCI *) obj;
+ QVirtioNet *interface = &v_net->net;
+ QOSGraphObject *pci_vobj = &v_net->pci_vdev.obj;
+
+ virtio_net_cleanup(interface);
+ qvirtio_pci_destructor(pci_vobj);
+}
+
+static void qvirtio_net_pci_start_hw(QOSGraphObject *obj)
+{
+ QVirtioNetPCI *v_net = (QVirtioNetPCI *) obj;
+ QVirtioNet *interface = &v_net->net;
+ QOSGraphObject *pci_vobj = &v_net->pci_vdev.obj;
+
+ qvirtio_pci_start_hw(pci_vobj);
+ virtio_net_setup(interface);
+}
+
+static void *qvirtio_net_pci_get_driver(void *object,
+ const char *interface)
+{
+ QVirtioNetPCI *v_net = object;
+ if (!g_strcmp0(interface, "pci-device")) {
+ return v_net->pci_vdev.pdev;
+ }
+ return qvirtio_net_get_driver(&v_net->net, interface);
+}
+
+static void *virtio_net_pci_create(void *pci_bus, QGuestAllocator *t_alloc,
+ void *addr)
+{
+ QVirtioNetPCI *virtio_bpci = g_new0(QVirtioNetPCI, 1);
+ QVirtioNet *interface = &virtio_bpci->net;
+ QOSGraphObject *obj = &virtio_bpci->pci_vdev.obj;
+
+ virtio_pci_init(&virtio_bpci->pci_vdev, pci_bus, addr);
+ interface->vdev = &virtio_bpci->pci_vdev.vdev;
+ alloc = t_alloc;
+
+ g_assert_cmphex(interface->vdev->device_type, ==, VIRTIO_ID_NET);
+
+ obj->destructor = qvirtio_net_pci_destructor;
+ obj->start_hw = qvirtio_net_pci_start_hw;
+ obj->get_driver = qvirtio_net_pci_get_driver;
+
+ return obj;
+}
+
+static void virtio_net_register_nodes(void)
+{
+ /* FIXME: every test using these nodes needs to setup a
+ * -netdev socket,id=hs0 otherwise QEMU is not going to start.
+ * Therefore, we do not include "produces" edge for virtio
+ * and pci-device yet.
+ */
+ QPCIAddress addr = {
+ .devfn = QPCI_DEVFN(4, 0),
+ };
+
+ QOSGraphEdgeOptions opts = { };
+
+ /* virtio-net-device */
+ opts.extra_device_opts = "netdev=hs0";
+ qos_node_create_driver("virtio-net-device",
+ virtio_net_device_create);
+ qos_node_consumes("virtio-net-device", "virtio-bus", &opts);
+ qos_node_produces("virtio-net-device", "virtio-net");
+
+ /* virtio-net-pci */
+ opts.extra_device_opts = "netdev=hs0,addr=04.0";
+ add_qpci_address(&opts, &addr);
+ qos_node_create_driver("virtio-net-pci", virtio_net_pci_create);
+ qos_node_consumes("virtio-net-pci", "pci-bus", &opts);
+ qos_node_produces("virtio-net-pci", "virtio-net");
+}
+
+libqos_init(virtio_net_register_nodes);
diff --git a/tests/libqos/virtio-net.h b/tests/libqos/virtio-net.h
new file mode 100644
index 0000000000..28238a1b20
--- /dev/null
+++ b/tests/libqos/virtio-net.h
@@ -0,0 +1,41 @@
+/*
+ * libqos driver framework
+ *
+ * Copyright (c) 2018 Emanuele Giuseppe Esposito <e.emanuelegiuseppe@gmail.com>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2 as published by the Free Software Foundation.
+ *
+ * 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 "libqos/qgraph.h"
+#include "libqos/virtio.h"
+#include "libqos/virtio-pci.h"
+
+typedef struct QVirtioNet QVirtioNet;
+typedef struct QVirtioNetPCI QVirtioNetPCI;
+typedef struct QVirtioNetDevice QVirtioNetDevice;
+
+struct QVirtioNet {
+ QVirtioDevice *vdev;
+ int n_queues;
+ QVirtQueue **queues;
+};
+
+struct QVirtioNetPCI {
+ QVirtioPCIDevice pci_vdev;
+ QVirtioNet net;
+};
+
+struct QVirtioNetDevice {
+ QOSGraphObject obj;
+ QVirtioNet net;
+};
diff --git a/tests/libqos/virtio-pci.c b/tests/libqos/virtio-pci.c
index 550dede0a2..993d347830 100644
--- a/tests/libqos/virtio-pci.c
+++ b/tests/libqos/virtio-pci.c
@@ -15,68 +15,39 @@
#include "libqos/pci-pc.h"
#include "libqos/malloc.h"
#include "libqos/malloc-pc.h"
+#include "libqos/qgraph.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 {
- void (*func)(QVirtioDevice *d, void *data);
- uint16_t device_type;
- bool has_slot;
- int slot;
- void *user_data;
-} QVirtioPCIForeachData;
-
-void qvirtio_pci_device_free(QVirtioPCIDevice *dev)
-{
- g_free(dev->pdev);
- g_free(dev);
-}
-
-static QVirtioPCIDevice *qpcidevice_to_qvirtiodevice(QPCIDevice *pdev)
-{
- QVirtioPCIDevice *vpcidev;
- vpcidev = g_malloc0(sizeof(*vpcidev));
-
- if (pdev) {
- vpcidev->pdev = pdev;
- vpcidev->vdev.device_type =
- qpci_config_readw(vpcidev->pdev, PCI_SUBSYSTEM_ID);
- }
-
- vpcidev->config_msix_entry = -1;
-
- return vpcidev;
-}
+/* virtio-pci is a superclass of all virtio-xxx-pci devices;
+ * the relation between virtio-pci and virtio-xxx-pci is implicit,
+ * and therefore virtio-pci does not produce virtio and is not
+ * reached by any edge, not even as a "contains" edge.
+ * In facts, every device is a QVirtioPCIDevice with
+ * additional fields, since every one has its own
+ * number of queues and various attributes.
+ * Virtio-pci provides default functions to start the
+ * hw and destroy the object, and nodes that want to
+ * override them should always remember to call the
+ * original qvirtio_pci_destructor and qvirtio_pci_start_hw.
+ */
-static void qvirtio_pci_foreach_callback(
- QPCIDevice *dev, int devfn, void *data)
+static inline bool qvirtio_pci_is_big_endian(QVirtioPCIDevice *dev)
{
- QVirtioPCIForeachData *d = data;
- QVirtioPCIDevice *vpcidev = qpcidevice_to_qvirtiodevice(dev);
-
- if (vpcidev->vdev.device_type == d->device_type &&
- (!d->has_slot || vpcidev->pdev->devfn == d->slot << 3)) {
- d->func(&vpcidev->vdev, d->user_data);
- } else {
- qvirtio_pci_device_free(vpcidev);
- }
-}
+ QPCIBus *bus = dev->pdev->bus;
-static void qvirtio_pci_assign_device(QVirtioDevice *d, void *data)
-{
- QVirtioPCIDevice **vpcidev = data;
- assert(!*vpcidev);
- *vpcidev = (QVirtioPCIDevice *)d;
+ /* FIXME: virtio 1.0 is always little-endian */
+ return qtest_big_endian(bus->qts);
}
#define CONFIG_BASE(dev) (VIRTIO_PCI_CONFIG_OFF((dev)->pdev->msix_enabled))
static uint8_t qvirtio_pci_config_readb(QVirtioDevice *d, uint64_t off)
{
- QVirtioPCIDevice *dev = (QVirtioPCIDevice *)d;
+ QVirtioPCIDevice *dev = container_of(d, QVirtioPCIDevice, vdev);
return qpci_io_readb(dev->pdev, dev->bar, CONFIG_BASE(dev) + off);
}
@@ -85,12 +56,12 @@ static uint8_t qvirtio_pci_config_readb(QVirtioDevice *d, uint64_t off)
* so with a big-endian guest the order has been reversed,
* reverse it again
* virtio-1.0 is always little-endian, like PCI, but this
- * case will be managed inside qvirtio_is_big_endian()
+ * case will be managed inside qvirtio_pci_is_big_endian()
*/
static uint16_t qvirtio_pci_config_readw(QVirtioDevice *d, uint64_t off)
{
- QVirtioPCIDevice *dev = (QVirtioPCIDevice *)d;
+ QVirtioPCIDevice *dev = container_of(d, QVirtioPCIDevice, vdev);
uint16_t value;
value = qpci_io_readw(dev->pdev, dev->bar, CONFIG_BASE(dev) + off);
@@ -102,7 +73,7 @@ static uint16_t qvirtio_pci_config_readw(QVirtioDevice *d, uint64_t off)
static uint32_t qvirtio_pci_config_readl(QVirtioDevice *d, uint64_t off)
{
- QVirtioPCIDevice *dev = (QVirtioPCIDevice *)d;
+ QVirtioPCIDevice *dev = container_of(d, QVirtioPCIDevice, vdev);
uint32_t value;
value = qpci_io_readl(dev->pdev, dev->bar, CONFIG_BASE(dev) + off);
@@ -114,7 +85,7 @@ static uint32_t qvirtio_pci_config_readl(QVirtioDevice *d, uint64_t off)
static uint64_t qvirtio_pci_config_readq(QVirtioDevice *d, uint64_t off)
{
- QVirtioPCIDevice *dev = (QVirtioPCIDevice *)d;
+ QVirtioPCIDevice *dev = container_of(d, QVirtioPCIDevice, vdev);
uint64_t val;
val = qpci_io_readq(dev->pdev, dev->bar, CONFIG_BASE(dev) + off);
@@ -127,37 +98,37 @@ static uint64_t qvirtio_pci_config_readq(QVirtioDevice *d, uint64_t off)
static uint32_t qvirtio_pci_get_features(QVirtioDevice *d)
{
- QVirtioPCIDevice *dev = (QVirtioPCIDevice *)d;
+ QVirtioPCIDevice *dev = container_of(d, QVirtioPCIDevice, vdev);
return qpci_io_readl(dev->pdev, dev->bar, VIRTIO_PCI_HOST_FEATURES);
}
static void qvirtio_pci_set_features(QVirtioDevice *d, uint32_t features)
{
- QVirtioPCIDevice *dev = (QVirtioPCIDevice *)d;
+ QVirtioPCIDevice *dev = container_of(d, QVirtioPCIDevice, vdev);
qpci_io_writel(dev->pdev, dev->bar, VIRTIO_PCI_GUEST_FEATURES, features);
}
static uint32_t qvirtio_pci_get_guest_features(QVirtioDevice *d)
{
- QVirtioPCIDevice *dev = (QVirtioPCIDevice *)d;
+ QVirtioPCIDevice *dev = container_of(d, QVirtioPCIDevice, vdev);
return qpci_io_readl(dev->pdev, dev->bar, VIRTIO_PCI_GUEST_FEATURES);
}
static uint8_t qvirtio_pci_get_status(QVirtioDevice *d)
{
- QVirtioPCIDevice *dev = (QVirtioPCIDevice *)d;
+ QVirtioPCIDevice *dev = container_of(d, QVirtioPCIDevice, vdev);
return qpci_io_readb(dev->pdev, dev->bar, VIRTIO_PCI_STATUS);
}
static void qvirtio_pci_set_status(QVirtioDevice *d, uint8_t status)
{
- QVirtioPCIDevice *dev = (QVirtioPCIDevice *)d;
+ QVirtioPCIDevice *dev = container_of(d, QVirtioPCIDevice, vdev);
qpci_io_writeb(dev->pdev, dev->bar, VIRTIO_PCI_STATUS, status);
}
static bool qvirtio_pci_get_queue_isr_status(QVirtioDevice *d, QVirtQueue *vq)
{
- QVirtioPCIDevice *dev = (QVirtioPCIDevice *)d;
+ QVirtioPCIDevice *dev = container_of(d, QVirtioPCIDevice, vdev);
QVirtQueuePCI *vqpci = (QVirtQueuePCI *)vq;
uint32_t data;
@@ -182,7 +153,7 @@ static bool qvirtio_pci_get_queue_isr_status(QVirtioDevice *d, QVirtQueue *vq)
static bool qvirtio_pci_get_config_isr_status(QVirtioDevice *d)
{
- QVirtioPCIDevice *dev = (QVirtioPCIDevice *)d;
+ QVirtioPCIDevice *dev = container_of(d, QVirtioPCIDevice, vdev);
uint32_t data;
if (dev->pdev->msix_enabled) {
@@ -206,19 +177,19 @@ static bool qvirtio_pci_get_config_isr_status(QVirtioDevice *d)
static void qvirtio_pci_queue_select(QVirtioDevice *d, uint16_t index)
{
- QVirtioPCIDevice *dev = (QVirtioPCIDevice *)d;
+ QVirtioPCIDevice *dev = container_of(d, QVirtioPCIDevice, vdev);
qpci_io_writeb(dev->pdev, dev->bar, VIRTIO_PCI_QUEUE_SEL, index);
}
static uint16_t qvirtio_pci_get_queue_size(QVirtioDevice *d)
{
- QVirtioPCIDevice *dev = (QVirtioPCIDevice *)d;
+ QVirtioPCIDevice *dev = container_of(d, QVirtioPCIDevice, vdev);
return qpci_io_readw(dev->pdev, dev->bar, VIRTIO_PCI_QUEUE_NUM);
}
static void qvirtio_pci_set_queue_address(QVirtioDevice *d, uint32_t pfn)
{
- QVirtioPCIDevice *dev = (QVirtioPCIDevice *)d;
+ QVirtioPCIDevice *dev = container_of(d, QVirtioPCIDevice, vdev);
qpci_io_writel(dev->pdev, dev->bar, VIRTIO_PCI_QUEUE_PFN, pfn);
}
@@ -270,7 +241,7 @@ static void qvirtio_pci_virtqueue_cleanup(QVirtQueue *vq,
static void qvirtio_pci_virtqueue_kick(QVirtioDevice *d, QVirtQueue *vq)
{
- QVirtioPCIDevice *dev = (QVirtioPCIDevice *)d;
+ QVirtioPCIDevice *dev = container_of(d, QVirtioPCIDevice, vdev);
qpci_io_writew(dev->pdev, dev->bar, VIRTIO_PCI_QUEUE_NOTIFY, vq->index);
}
@@ -294,47 +265,6 @@ const QVirtioBus qvirtio_pci = {
.virtqueue_kick = qvirtio_pci_virtqueue_kick,
};
-static void qvirtio_pci_foreach(QPCIBus *bus, uint16_t device_type,
- bool has_slot, int slot,
- void (*func)(QVirtioDevice *d, void *data), void *data)
-{
- QVirtioPCIForeachData d = { .func = func,
- .device_type = device_type,
- .has_slot = has_slot,
- .slot = slot,
- .user_data = data };
-
- qpci_device_foreach(bus, PCI_VENDOR_ID_REDHAT_QUMRANET, -1,
- qvirtio_pci_foreach_callback, &d);
-}
-
-QVirtioPCIDevice *qvirtio_pci_device_find(QPCIBus *bus, uint16_t device_type)
-{
- QVirtioPCIDevice *dev = NULL;
-
- qvirtio_pci_foreach(bus, device_type, false, 0,
- qvirtio_pci_assign_device, &dev);
-
- if (dev) {
- dev->vdev.bus = &qvirtio_pci;
- }
-
- return dev;
-}
-
-QVirtioPCIDevice *qvirtio_pci_device_find_slot(QPCIBus *bus,
- uint16_t device_type, int slot)
-{
- QVirtioPCIDevice *dev = NULL;
-
- qvirtio_pci_foreach(bus, device_type, true, slot,
- qvirtio_pci_assign_device, &dev);
-
- dev->vdev.bus = &qvirtio_pci;
-
- return dev;
-}
-
void qvirtio_pci_device_enable(QVirtioPCIDevice *d)
{
qpci_device_enable(d->pdev);
@@ -416,3 +346,54 @@ void qvirtio_pci_set_msix_configuration_vector(QVirtioPCIDevice *d,
vector = qpci_io_readw(d->pdev, d->bar, VIRTIO_MSI_CONFIG_VECTOR);
g_assert_cmphex(vector, !=, VIRTIO_MSI_NO_VECTOR);
}
+
+void qvirtio_pci_destructor(QOSGraphObject *obj)
+{
+ QVirtioPCIDevice *dev = (QVirtioPCIDevice *)obj;
+ qvirtio_pci_device_disable(dev);
+ g_free(dev->pdev);
+}
+
+void qvirtio_pci_start_hw(QOSGraphObject *obj)
+{
+ QVirtioPCIDevice *dev = (QVirtioPCIDevice *)obj;
+ qvirtio_pci_device_enable(dev);
+ qvirtio_start_device(&dev->vdev);
+}
+
+static void qvirtio_pci_init_from_pcidev(QVirtioPCIDevice *dev, QPCIDevice *pci_dev)
+{
+ dev->pdev = pci_dev;
+ dev->vdev.device_type = qpci_config_readw(pci_dev, PCI_SUBSYSTEM_ID);
+
+ dev->config_msix_entry = -1;
+
+ dev->vdev.bus = &qvirtio_pci;
+ dev->vdev.big_endian = qvirtio_pci_is_big_endian(dev);
+
+ /* each virtio-xxx-pci device should override at least this function */
+ dev->obj.get_driver = NULL;
+ dev->obj.start_hw = qvirtio_pci_start_hw;
+ dev->obj.destructor = qvirtio_pci_destructor;
+}
+
+void virtio_pci_init(QVirtioPCIDevice *dev, QPCIBus *bus, QPCIAddress * addr)
+{
+ QPCIDevice *pci_dev = qpci_device_find(bus, addr->devfn);
+ g_assert_nonnull(pci_dev);
+ qvirtio_pci_init_from_pcidev(dev, pci_dev);
+}
+
+QVirtioPCIDevice *virtio_pci_new(QPCIBus *bus, QPCIAddress * addr)
+{
+ QVirtioPCIDevice *dev;
+ QPCIDevice *pci_dev = qpci_device_find(bus, addr->devfn);
+ if (!pci_dev) {
+ return NULL;
+ }
+
+ dev = g_new0(QVirtioPCIDevice, 1);
+ qvirtio_pci_init_from_pcidev(dev, pci_dev);
+ dev->obj.free = g_free;
+ return dev;
+}
diff --git a/tests/libqos/virtio-pci.h b/tests/libqos/virtio-pci.h
index 6ef19094cb..728b4715f1 100644
--- a/tests/libqos/virtio-pci.h
+++ b/tests/libqos/virtio-pci.h
@@ -12,8 +12,10 @@
#include "libqos/virtio.h"
#include "libqos/pci.h"
+#include "libqos/qgraph.h"
typedef struct QVirtioPCIDevice {
+ QOSGraphObject obj;
QVirtioDevice vdev;
QPCIDevice *pdev;
QPCIBar bar;
@@ -31,10 +33,18 @@ typedef struct QVirtQueuePCI {
extern const QVirtioBus qvirtio_pci;
-QVirtioPCIDevice *qvirtio_pci_device_find(QPCIBus *bus, uint16_t device_type);
-QVirtioPCIDevice *qvirtio_pci_device_find_slot(QPCIBus *bus,
- uint16_t device_type, int slot);
-void qvirtio_pci_device_free(QVirtioPCIDevice *dev);
+void virtio_pci_init(QVirtioPCIDevice *dev, QPCIBus *bus, QPCIAddress * addr);
+QVirtioPCIDevice *virtio_pci_new(QPCIBus *bus, QPCIAddress * addr);
+
+/* virtio-pci object functions available for subclasses that
+ * override the original start_hw and destroy
+ * function. All virtio-xxx-pci subclass that override must
+ * take care of calling these two functions in the respective
+ * places
+ */
+void qvirtio_pci_destructor(QOSGraphObject *obj);
+void qvirtio_pci_start_hw(QOSGraphObject *obj);
+
void qvirtio_pci_device_enable(QVirtioPCIDevice *d);
void qvirtio_pci_device_disable(QVirtioPCIDevice *d);
diff --git a/tests/libqos/virtio-rng.c b/tests/libqos/virtio-rng.c
new file mode 100644
index 0000000000..a1d2c7671c
--- /dev/null
+++ b/tests/libqos/virtio-rng.c
@@ -0,0 +1,110 @@
+/*
+ * libqos driver framework
+ *
+ * Copyright (c) 2018 Emanuele Giuseppe Esposito <e.emanuelegiuseppe@gmail.com>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2 as published by the Free Software Foundation.
+ *
+ * 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 "libqos/qgraph.h"
+#include "libqos/virtio-rng.h"
+
+/* virtio-rng-device */
+static void *qvirtio_rng_get_driver(QVirtioRng *v_rng,
+ const char *interface)
+{
+ if (!g_strcmp0(interface, "virtio-rng")) {
+ return v_rng;
+ }
+ if (!g_strcmp0(interface, "virtio")) {
+ return v_rng->vdev;
+ }
+
+ fprintf(stderr, "%s not present in virtio-rng-device\n", interface);
+ g_assert_not_reached();
+}
+
+static void *qvirtio_rng_device_get_driver(void *object,
+ const char *interface)
+{
+ QVirtioRngDevice *v_rng = object;
+ return qvirtio_rng_get_driver(&v_rng->rng, interface);
+}
+
+static void *virtio_rng_device_create(void *virtio_dev,
+ QGuestAllocator *t_alloc,
+ void *addr)
+{
+ QVirtioRngDevice *virtio_rdevice = g_new0(QVirtioRngDevice, 1);
+ QVirtioRng *interface = &virtio_rdevice->rng;
+
+ interface->vdev = virtio_dev;
+
+ virtio_rdevice->obj.get_driver = qvirtio_rng_device_get_driver;
+
+ return &virtio_rdevice->obj;
+}
+
+/* virtio-rng-pci */
+static void *qvirtio_rng_pci_get_driver(void *object, const char *interface)
+{
+ QVirtioRngPCI *v_rng = object;
+ if (!g_strcmp0(interface, "pci-device")) {
+ return v_rng->pci_vdev.pdev;
+ }
+ return qvirtio_rng_get_driver(&v_rng->rng, interface);
+}
+
+static void *virtio_rng_pci_create(void *pci_bus, QGuestAllocator *t_alloc,
+ void *addr)
+{
+ QVirtioRngPCI *virtio_rpci = g_new0(QVirtioRngPCI, 1);
+ QVirtioRng *interface = &virtio_rpci->rng;
+ QOSGraphObject *obj = &virtio_rpci->pci_vdev.obj;
+
+ virtio_pci_init(&virtio_rpci->pci_vdev, pci_bus, addr);
+ interface->vdev = &virtio_rpci->pci_vdev.vdev;
+
+ obj->get_driver = qvirtio_rng_pci_get_driver;
+
+ return obj;
+}
+
+static void virtio_rng_register_nodes(void)
+{
+ QPCIAddress addr = {
+ .devfn = QPCI_DEVFN(4, 0),
+ };
+
+ QOSGraphEdgeOptions opts = {
+ .extra_device_opts = "addr=04.0",
+ };
+
+ /* virtio-rng-device */
+ qos_node_create_driver("virtio-rng-device", virtio_rng_device_create);
+ qos_node_consumes("virtio-rng-device", "virtio-bus", NULL);
+ qos_node_produces("virtio-rng-device", "virtio");
+ qos_node_produces("virtio-rng-device", "virtio-rng");
+
+ /* virtio-rng-pci */
+ add_qpci_address(&opts, &addr);
+ qos_node_create_driver("virtio-rng-pci", virtio_rng_pci_create);
+ qos_node_consumes("virtio-rng-pci", "pci-bus", &opts);
+ qos_node_produces("virtio-rng-pci", "pci-device");
+ qos_node_produces("virtio-rng-pci", "virtio");
+ qos_node_produces("virtio-rng-pci", "virtio-rng");
+}
+
+libqos_init(virtio_rng_register_nodes);
diff --git a/tests/libqos/virtio-rng.h b/tests/libqos/virtio-rng.h
new file mode 100644
index 0000000000..fbba988875
--- /dev/null
+++ b/tests/libqos/virtio-rng.h
@@ -0,0 +1,39 @@
+/*
+ * libqos driver framework
+ *
+ * Copyright (c) 2018 Emanuele Giuseppe Esposito <e.emanuelegiuseppe@gmail.com>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2 as published by the Free Software Foundation.
+ *
+ * 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 "libqos/qgraph.h"
+#include "libqos/virtio.h"
+#include "libqos/virtio-pci.h"
+
+typedef struct QVirtioRng QVirtioRng;
+typedef struct QVirtioRngPCI QVirtioRngPCI;
+typedef struct QVirtioRngDevice QVirtioRngDevice;
+
+struct QVirtioRng {
+ QVirtioDevice *vdev;
+};
+
+struct QVirtioRngPCI {
+ QVirtioPCIDevice pci_vdev;
+ QVirtioRng rng;
+};
+
+struct QVirtioRngDevice {
+ QOSGraphObject obj;
+ QVirtioRng rng;
+};
diff --git a/tests/libqos/virtio-scsi.c b/tests/libqos/virtio-scsi.c
new file mode 100644
index 0000000000..482684d0bc
--- /dev/null
+++ b/tests/libqos/virtio-scsi.c
@@ -0,0 +1,117 @@
+/*
+ * libqos driver framework
+ *
+ * Copyright (c) 2018 Emanuele Giuseppe Esposito <e.emanuelegiuseppe@gmail.com>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2 as published by the Free Software Foundation.
+ *
+ * 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 "standard-headers/linux/virtio_ids.h"
+#include "libqos/qgraph.h"
+#include "libqos/virtio-scsi.h"
+
+/* virtio-scsi-device */
+static void *qvirtio_scsi_get_driver(QVirtioSCSI *v_scsi,
+ const char *interface)
+{
+ if (!g_strcmp0(interface, "virtio-scsi")) {
+ return v_scsi;
+ }
+ if (!g_strcmp0(interface, "virtio")) {
+ return v_scsi->vdev;
+ }
+
+ fprintf(stderr, "%s not present in virtio-scsi-device\n", interface);
+ g_assert_not_reached();
+}
+
+static void *qvirtio_scsi_device_get_driver(void *object,
+ const char *interface)
+{
+ QVirtioSCSIDevice *v_scsi = object;
+ return qvirtio_scsi_get_driver(&v_scsi->scsi, interface);
+}
+
+static void *virtio_scsi_device_create(void *virtio_dev,
+ QGuestAllocator *t_alloc,
+ void *addr)
+{
+ QVirtioSCSIDevice *virtio_bdevice = g_new0(QVirtioSCSIDevice, 1);
+ QVirtioSCSI *interface = &virtio_bdevice->scsi;
+
+ interface->vdev = virtio_dev;
+
+ virtio_bdevice->obj.get_driver = qvirtio_scsi_device_get_driver;
+
+ return &virtio_bdevice->obj;
+}
+
+/* virtio-scsi-pci */
+static void *qvirtio_scsi_pci_get_driver(void *object,
+ const char *interface)
+{
+ QVirtioSCSIPCI *v_scsi = object;
+ if (!g_strcmp0(interface, "pci-device")) {
+ return v_scsi->pci_vdev.pdev;
+ }
+ return qvirtio_scsi_get_driver(&v_scsi->scsi, interface);
+}
+
+static void *virtio_scsi_pci_create(void *pci_bus,
+ QGuestAllocator *t_alloc,
+ void *addr)
+{
+ QVirtioSCSIPCI *virtio_spci = g_new0(QVirtioSCSIPCI, 1);
+ QVirtioSCSI *interface = &virtio_spci->scsi;
+ QOSGraphObject *obj = &virtio_spci->pci_vdev.obj;
+
+ virtio_pci_init(&virtio_spci->pci_vdev, pci_bus, addr);
+ interface->vdev = &virtio_spci->pci_vdev.vdev;
+
+ g_assert_cmphex(interface->vdev->device_type, ==, VIRTIO_ID_SCSI);
+
+ obj->get_driver = qvirtio_scsi_pci_get_driver;
+
+ return obj;
+}
+
+static void virtio_scsi_register_nodes(void)
+{
+ QPCIAddress addr = {
+ .devfn = QPCI_DEVFN(4, 0),
+ };
+
+ QOSGraphEdgeOptions opts = {
+ .before_cmd_line = "-drive id=drv0,if=none,file=null-co://,format=raw",
+ .after_cmd_line = "-device scsi-hd,bus=vs0.0,drive=drv0",
+ };
+
+ /* virtio-scsi-device */
+ opts.extra_device_opts = "id=vs0";
+ qos_node_create_driver("virtio-scsi-device",
+ virtio_scsi_device_create);
+ qos_node_consumes("virtio-scsi-device", "virtio-bus", &opts);
+ qos_node_produces("virtio-scsi-device", "virtio-scsi");
+
+ /* virtio-scsi-pci */
+ opts.extra_device_opts = "id=vs0,addr=04.0";
+ add_qpci_address(&opts, &addr);
+ qos_node_create_driver("virtio-scsi-pci", virtio_scsi_pci_create);
+ qos_node_consumes("virtio-scsi-pci", "pci-bus", &opts);
+ qos_node_produces("virtio-scsi-pci", "pci-device");
+ qos_node_produces("virtio-scsi-pci", "virtio-scsi");
+}
+
+libqos_init(virtio_scsi_register_nodes);
diff --git a/tests/libqos/virtio-scsi.h b/tests/libqos/virtio-scsi.h
new file mode 100644
index 0000000000..17a47beddc
--- /dev/null
+++ b/tests/libqos/virtio-scsi.h
@@ -0,0 +1,39 @@
+/*
+ * libqos driver framework
+ *
+ * Copyright (c) 2018 Emanuele Giuseppe Esposito <e.emanuelegiuseppe@gmail.com>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2 as published by the Free Software Foundation.
+ *
+ * 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 "libqos/qgraph.h"
+#include "libqos/virtio.h"
+#include "libqos/virtio-pci.h"
+
+typedef struct QVirtioSCSI QVirtioSCSI;
+typedef struct QVirtioSCSIPCI QVirtioSCSIPCI;
+typedef struct QVirtioSCSIDevice QVirtioSCSIDevice;
+
+struct QVirtioSCSI {
+ QVirtioDevice *vdev;
+};
+
+struct QVirtioSCSIPCI {
+ QVirtioPCIDevice pci_vdev;
+ QVirtioSCSI scsi;
+};
+
+struct QVirtioSCSIDevice {
+ QOSGraphObject obj;
+ QVirtioSCSI scsi;
+};
diff --git a/tests/libqos/virtio-serial.c b/tests/libqos/virtio-serial.c
new file mode 100644
index 0000000000..91cedefb8d
--- /dev/null
+++ b/tests/libqos/virtio-serial.c
@@ -0,0 +1,110 @@
+/*
+ * libqos driver framework
+ *
+ * Copyright (c) 2018 Emanuele Giuseppe Esposito <e.emanuelegiuseppe@gmail.com>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2 as published by the Free Software Foundation.
+ *
+ * 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 "libqos/qgraph.h"
+#include "libqos/virtio-serial.h"
+
+static void *qvirtio_serial_get_driver(QVirtioSerial *v_serial,
+ const char *interface)
+{
+ if (!g_strcmp0(interface, "virtio-serial")) {
+ return v_serial;
+ }
+ if (!g_strcmp0(interface, "virtio")) {
+ return v_serial->vdev;
+ }
+
+ fprintf(stderr, "%s not present in virtio-serial-device\n", interface);
+ g_assert_not_reached();
+}
+
+static void *qvirtio_serial_device_get_driver(void *object,
+ const char *interface)
+{
+ QVirtioSerialDevice *v_serial = object;
+ return qvirtio_serial_get_driver(&v_serial->serial, interface);
+}
+
+static void *virtio_serial_device_create(void *virtio_dev,
+ QGuestAllocator *t_alloc,
+ void *addr)
+{
+ QVirtioSerialDevice *virtio_device = g_new0(QVirtioSerialDevice, 1);
+ QVirtioSerial *interface = &virtio_device->serial;
+
+ interface->vdev = virtio_dev;
+
+ virtio_device->obj.get_driver = qvirtio_serial_device_get_driver;
+
+ return &virtio_device->obj;
+}
+
+/* virtio-serial-pci */
+static void *qvirtio_serial_pci_get_driver(void *object, const char *interface)
+{
+ QVirtioSerialPCI *v_serial = object;
+ if (!g_strcmp0(interface, "pci-device")) {
+ return v_serial->pci_vdev.pdev;
+ }
+ return qvirtio_serial_get_driver(&v_serial->serial, interface);
+}
+
+static void *virtio_serial_pci_create(void *pci_bus, QGuestAllocator *t_alloc,
+ void *addr)
+{
+ QVirtioSerialPCI *virtio_spci = g_new0(QVirtioSerialPCI, 1);
+ QVirtioSerial *interface = &virtio_spci->serial;
+ QOSGraphObject *obj = &virtio_spci->pci_vdev.obj;
+
+ virtio_pci_init(&virtio_spci->pci_vdev, pci_bus, addr);
+ interface->vdev = &virtio_spci->pci_vdev.vdev;
+
+ obj->get_driver = qvirtio_serial_pci_get_driver;
+
+ return obj;
+}
+
+static void virtio_serial_register_nodes(void)
+{
+ QPCIAddress addr = {
+ .devfn = QPCI_DEVFN(4, 0),
+ };
+
+ QOSGraphEdgeOptions edge_opts = { };
+
+ /* virtio-serial-device */
+ edge_opts.extra_device_opts = "id=vser0";
+ qos_node_create_driver("virtio-serial-device",
+ virtio_serial_device_create);
+ qos_node_consumes("virtio-serial-device", "virtio-bus", &edge_opts);
+ qos_node_produces("virtio-serial-device", "virtio");
+ qos_node_produces("virtio-serial-device", "virtio-serial");
+
+ /* virtio-serial-pci */
+ edge_opts.extra_device_opts = "id=vser0,addr=04.0";
+ add_qpci_address(&edge_opts, &addr);
+ qos_node_create_driver("virtio-serial-pci", virtio_serial_pci_create);
+ qos_node_consumes("virtio-serial-pci", "pci-bus", &edge_opts);
+ qos_node_produces("virtio-serial-pci", "pci-device");
+ qos_node_produces("virtio-serial-pci", "virtio");
+ qos_node_produces("virtio-serial-pci", "virtio-serial");
+}
+
+libqos_init(virtio_serial_register_nodes);
diff --git a/tests/libqos/virtio-serial.h b/tests/libqos/virtio-serial.h
new file mode 100644
index 0000000000..b7e2a5d178
--- /dev/null
+++ b/tests/libqos/virtio-serial.h
@@ -0,0 +1,39 @@
+/*
+ * libqos driver framework
+ *
+ * Copyright (c) 2018 Emanuele Giuseppe Esposito <e.emanuelegiuseppe@gmail.com>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2 as published by the Free Software Foundation.
+ *
+ * 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 "libqos/qgraph.h"
+#include "libqos/virtio.h"
+#include "libqos/virtio-pci.h"
+
+typedef struct QVirtioSerial QVirtioSerial;
+typedef struct QVirtioSerialPCI QVirtioSerialPCI;
+typedef struct QVirtioSerialDevice QVirtioSerialDevice;
+
+struct QVirtioSerial {
+ QVirtioDevice *vdev;
+};
+
+struct QVirtioSerialPCI {
+ QVirtioPCIDevice pci_vdev;
+ QVirtioSerial serial;
+};
+
+struct QVirtioSerialDevice {
+ QOSGraphObject obj;
+ QVirtioSerial serial;
+};
diff --git a/tests/libqos/virtio.c b/tests/libqos/virtio.c
index 0dad5c19ac..5e8f39b4d3 100644
--- a/tests/libqos/virtio.c
+++ b/tests/libqos/virtio.c
@@ -40,6 +40,7 @@ uint32_t qvirtio_get_features(QVirtioDevice *d)
void qvirtio_set_features(QVirtioDevice *d, uint32_t features)
{
+ d->features = features;
d->bus->set_features(d, features);
}
@@ -349,19 +350,14 @@ void qvirtqueue_set_used_event(QVirtQueue *vq, uint16_t idx)
writew(vq->avail + 4 + (2 * vq->size), idx);
}
-/*
- * qvirtio_get_dev_type:
- * Returns: the preferred virtio bus/device type for the current architecture.
- */
-const char *qvirtio_get_dev_type(void)
+void qvirtio_start_device(QVirtioDevice *vdev)
{
- const char *arch = qtest_get_arch();
-
- if (g_str_equal(arch, "arm") || g_str_equal(arch, "aarch64")) {
- return "device"; /* for virtio-mmio */
- } else if (g_str_equal(arch, "s390x")) {
- return "ccw";
- } else {
- return "pci";
- }
+ qvirtio_reset(vdev);
+ qvirtio_set_acknowledge(vdev);
+ qvirtio_set_driver(vdev);
+}
+
+bool qvirtio_is_big_endian(QVirtioDevice *d)
+{
+ return d->big_endian;
}
diff --git a/tests/libqos/virtio.h b/tests/libqos/virtio.h
index 69b5b13840..51d2359ace 100644
--- a/tests/libqos/virtio.h
+++ b/tests/libqos/virtio.h
@@ -21,6 +21,8 @@ typedef struct QVirtioDevice {
const QVirtioBus *bus;
/* Device type */
uint16_t device_type;
+ uint64_t features;
+ bool big_endian;
} QVirtioDevice;
typedef struct QVirtQueue {
@@ -90,12 +92,6 @@ struct QVirtioBus {
void (*virtqueue_kick)(QVirtioDevice *d, QVirtQueue *vq);
};
-static inline bool qvirtio_is_big_endian(QVirtioDevice *d)
-{
- /* FIXME: virtio 1.0 is always little-endian */
- return qtest_big_endian(global_qtest);
-}
-
static inline uint32_t qvring_size(uint32_t num, uint32_t align)
{
return ((sizeof(struct vring_desc) * num + sizeof(uint16_t) * (3 + num)
@@ -109,6 +105,7 @@ uint32_t qvirtio_config_readl(QVirtioDevice *d, uint64_t addr);
uint64_t qvirtio_config_readq(QVirtioDevice *d, uint64_t addr);
uint32_t qvirtio_get_features(QVirtioDevice *d);
void qvirtio_set_features(QVirtioDevice *d, uint32_t features);
+bool qvirtio_is_big_endian(QVirtioDevice *d);
void qvirtio_reset(QVirtioDevice *d);
void qvirtio_set_acknowledge(QVirtioDevice *d);
@@ -145,6 +142,6 @@ bool qvirtqueue_get_buf(QVirtQueue *vq, uint32_t *desc_idx, uint32_t *len);
void qvirtqueue_set_used_event(QVirtQueue *vq, uint16_t idx);
-const char *qvirtio_get_dev_type(void);
+void qvirtio_start_device(QVirtioDevice *vdev);
#endif
diff --git a/tests/libqos/x86_64_pc-machine.c b/tests/libqos/x86_64_pc-machine.c
new file mode 100644
index 0000000000..8bd0360ba9
--- /dev/null
+++ b/tests/libqos/x86_64_pc-machine.c
@@ -0,0 +1,114 @@
+/*
+ * libqos driver framework
+ *
+ * Copyright (c) 2018 Emanuele Giuseppe Esposito <e.emanuelegiuseppe@gmail.com>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2 as published by the Free Software Foundation.
+ *
+ * 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 "libqos/qgraph.h"
+#include "pci-pc.h"
+#include "malloc-pc.h"
+
+typedef struct QX86PCMachine QX86PCMachine;
+typedef struct i440FX_pcihost i440FX_pcihost;
+typedef struct QSDHCI_PCI QSDHCI_PCI;
+
+struct i440FX_pcihost {
+ QOSGraphObject obj;
+ QPCIBusPC pci;
+};
+
+struct QX86PCMachine {
+ QOSGraphObject obj;
+ QGuestAllocator alloc;
+ i440FX_pcihost bridge;
+};
+
+/* i440FX_pcihost */
+
+static QOSGraphObject *i440FX_host_get_device(void *obj, const char *device)
+{
+ i440FX_pcihost *host = obj;
+ if (!g_strcmp0(device, "pci-bus-pc")) {
+ return &host->pci.obj;
+ }
+ fprintf(stderr, "%s not present in i440FX-pcihost\n", device);
+ g_assert_not_reached();
+}
+
+static void qos_create_i440FX_host(i440FX_pcihost *host,
+ QTestState *qts,
+ QGuestAllocator *alloc)
+{
+ host->obj.get_device = i440FX_host_get_device;
+ qpci_init_pc(&host->pci, qts, alloc);
+}
+
+/* x86_64/pc machine */
+
+static void pc_destructor(QOSGraphObject *obj)
+{
+ QX86PCMachine *machine = (QX86PCMachine *) obj;
+ alloc_destroy(&machine->alloc);
+}
+
+static void *pc_get_driver(void *object, const char *interface)
+{
+ QX86PCMachine *machine = object;
+ if (!g_strcmp0(interface, "memory")) {
+ return &machine->alloc;
+ }
+
+ fprintf(stderr, "%s not present in x86_64/pc\n", interface);
+ g_assert_not_reached();
+}
+
+static QOSGraphObject *pc_get_device(void *obj, const char *device)
+{
+ QX86PCMachine *machine = obj;
+ if (!g_strcmp0(device, "i440FX-pcihost")) {
+ return &machine->bridge.obj;
+ }
+
+ fprintf(stderr, "%s not present in x86_64/pc\n", device);
+ g_assert_not_reached();
+}
+
+static void *qos_create_machine_pc(QTestState *qts)
+{
+ QX86PCMachine *machine = g_new0(QX86PCMachine, 1);
+ machine->obj.get_device = pc_get_device;
+ machine->obj.get_driver = pc_get_driver;
+ machine->obj.destructor = pc_destructor;
+ pc_alloc_init(&machine->alloc, qts, ALLOC_NO_FLAGS);
+ qos_create_i440FX_host(&machine->bridge, qts, &machine->alloc);
+
+ return &machine->obj;
+}
+
+static void pc_machine_register_nodes(void)
+{
+ qos_node_create_machine("i386/pc", qos_create_machine_pc);
+ qos_node_contains("i386/pc", "i440FX-pcihost", NULL);
+
+ qos_node_create_machine("x86_64/pc", qos_create_machine_pc);
+ qos_node_contains("x86_64/pc", "i440FX-pcihost", NULL);
+
+ qos_node_create_driver("i440FX-pcihost", NULL);
+ qos_node_contains("i440FX-pcihost", "pci-bus-pc", NULL);
+}
+
+libqos_init(pc_machine_register_nodes);
diff --git a/tests/libqtest.h b/tests/libqtest.h
index 5937f91912..a16acd58a6 100644
--- a/tests/libqtest.h
+++ b/tests/libqtest.h
@@ -17,6 +17,9 @@
#ifndef LIBQTEST_H
#define LIBQTEST_H
+#include "qapi/qmp/qobject.h"
+#include "qapi/qmp/qdict.h"
+
typedef struct QTestState QTestState;
extern QTestState *global_qtest;
@@ -598,6 +601,9 @@ static inline QTestState *qtest_start(const char *args)
*/
static inline void qtest_end(void)
{
+ if (!global_qtest) {
+ return;
+ }
qtest_quit(global_qtest);
global_qtest = NULL;
}
diff --git a/tests/m48t59-test.c b/tests/m48t59-test.c
index 4abf9c605c..b94a1230f7 100644
--- a/tests/m48t59-test.c
+++ b/tests/m48t59-test.c
@@ -199,9 +199,9 @@ static void bcd_check_time(void)
t = (long)mktime(datep);
s = (long)mktime(&start);
if (t < s) {
- g_test_message("RTC is %ld second(s) behind wall-clock\n", (s - t));
+ g_test_message("RTC is %ld second(s) behind wall-clock", (s - t));
} else {
- g_test_message("RTC is %ld second(s) ahead of wall-clock\n", (t - s));
+ g_test_message("RTC is %ld second(s) ahead of wall-clock", (t - s));
}
g_assert_cmpint(ABS(t - s), <=, wiggle);
diff --git a/tests/megasas-test.c b/tests/megasas-test.c
index 81837e14af..33aa97042c 100644
--- a/tests/megasas-test.c
+++ b/tests/megasas-test.c
@@ -10,55 +10,49 @@
#include "qemu/osdep.h"
#include "libqtest.h"
#include "qemu/bswap.h"
-#include "libqos/libqos-pc.h"
-#include "libqos/libqos-spapr.h"
+#include "libqos/qgraph.h"
+#include "libqos/pci.h"
-static QOSState *qmegasas_start(const char *extra_opts)
+typedef struct QMegasas QMegasas;
+
+struct QMegasas {
+ QOSGraphObject obj;
+ QPCIDevice dev;
+};
+
+static void *megasas_get_driver(void *obj, const char *interface)
{
- QOSState *qs;
- const char *arch = qtest_get_arch();
- const char *cmd = "-drive id=hd0,if=none,file=null-co://,format=raw "
- "-device megasas,id=scsi0,addr=04.0 "
- "-device scsi-hd,bus=scsi0.0,drive=hd0 %s";
-
- if (strcmp(arch, "i386") == 0 || strcmp(arch, "x86_64") == 0) {
- qs = qtest_pc_boot(cmd, extra_opts ? : "");
- global_qtest = qs->qts;
- return qs;
+ QMegasas *megasas = obj;
+
+ if (!g_strcmp0(interface, "pci-device")) {
+ return &megasas->dev;
}
- g_printerr("virtio-scsi tests are only available on x86 or ppc64\n");
- exit(EXIT_FAILURE);
+ fprintf(stderr, "%s not present in megasas\n", interface);
+ g_assert_not_reached();
}
-static void qmegasas_stop(QOSState *qs)
+static void *megasas_create(void *pci_bus, QGuestAllocator *alloc, void *addr)
{
- qtest_shutdown(qs);
-}
+ QMegasas *megasas = g_new0(QMegasas, 1);
+ QPCIBus *bus = pci_bus;
-/* Tests only initialization so far. TODO: Replace with functional tests */
-static void pci_nop(void)
-{
- QOSState *qs;
+ qpci_device_init(&megasas->dev, bus, addr);
+ megasas->obj.get_driver = megasas_get_driver;
- qs = qmegasas_start(NULL);
- qmegasas_stop(qs);
+ return &megasas->obj;
}
/* This used to cause a NULL pointer dereference. */
-static void megasas_pd_get_info_fuzz(void)
+static void megasas_pd_get_info_fuzz(void *obj, void *data, QGuestAllocator *alloc)
{
- QPCIDevice *dev;
- QOSState *qs;
+ QMegasas *megasas = obj;
+ QPCIDevice *dev = &megasas->dev;
QPCIBar bar;
uint32_t context[256];
uint64_t context_pa;
int i;
- qs = qmegasas_start(NULL);
- dev = qpci_device_find(qs->pcibus, QPCI_DEVFN(4,0));
- g_assert(dev != NULL);
-
qpci_device_enable(dev);
bar = qpci_iomap(dev, 0, NULL);
@@ -71,19 +65,25 @@ static void megasas_pd_get_info_fuzz(void)
context[6] = cpu_to_le32(0x02020000);
context[7] = cpu_to_le32(0);
- context_pa = qmalloc(qs, sizeof(context));
+ context_pa = guest_alloc(alloc, sizeof(context));
memwrite(context_pa, context, sizeof(context));
qpci_io_writel(dev, bar, 0x40, context_pa);
-
- g_free(dev);
- qmegasas_stop(qs);
}
-int main(int argc, char **argv)
+static void megasas_register_nodes(void)
{
- g_test_init(&argc, &argv, NULL);
- qtest_add_func("/megasas/pci/nop", pci_nop);
- qtest_add_func("/megasas/dcmd/pd-get-info/fuzz", megasas_pd_get_info_fuzz);
+ QOSGraphEdgeOptions opts = {
+ .extra_device_opts = "addr=04.0,id=scsi0",
+ .before_cmd_line = "-drive id=drv0,if=none,file=null-co://,format=raw",
+ .after_cmd_line = "-device scsi-hd,bus=scsi0.0,drive=drv0",
+ };
+
+ add_qpci_address(&opts, &(QPCIAddress) { .devfn = QPCI_DEVFN(4, 0) });
+
+ qos_node_create_driver("megasas", megasas_create);
+ qos_node_consumes("megasas", "pci-bus", &opts);
+ qos_node_produces("megasas", "pci-device");
- return g_test_run();
+ qos_add_test("dcmd/pd-get-info/fuzz", "megasas", megasas_pd_get_info_fuzz, NULL);
}
+libqos_init(megasas_register_nodes);
diff --git a/tests/migration-test.c b/tests/migration-test.c
index e3617ceaca..48dc20a2ae 100644
--- a/tests/migration-test.c
+++ b/tests/migration-test.c
@@ -1066,7 +1066,7 @@ int main(int argc, char **argv)
tmpfs = mkdtemp(template);
if (!tmpfs) {
- g_test_message("mkdtemp on path (%s): %s\n", template, strerror(errno));
+ g_test_message("mkdtemp on path (%s): %s", template, strerror(errno));
}
g_assert(tmpfs);
@@ -1087,7 +1087,7 @@ int main(int argc, char **argv)
ret = rmdir(tmpfs);
if (ret != 0) {
- g_test_message("unable to rmdir: path (%s): %s\n",
+ g_test_message("unable to rmdir: path (%s): %s",
tmpfs, strerror(errno));
}
diff --git a/tests/ne2000-test.c b/tests/ne2000-test.c
index b7cf3dd2f5..097c2eec6c 100644
--- a/tests/ne2000-test.c
+++ b/tests/ne2000-test.c
@@ -9,23 +9,49 @@
#include "qemu/osdep.h"
#include "libqtest.h"
+#include "libqos/qgraph.h"
+#include "libqos/pci.h"
-/* Tests only initialization so far. TODO: Replace with functional tests */
-static void pci_nop(void)
+typedef struct QNe2k_pci QNe2k_pci;
+
+struct QNe2k_pci {
+ QOSGraphObject obj;
+ QPCIDevice dev;
+};
+
+static void *ne2k_pci_get_driver(void *obj, const char *interface)
{
+ QNe2k_pci *ne2k_pci = obj;
+
+ if (!g_strcmp0(interface, "pci-device")) {
+ return &ne2k_pci->dev;
+ }
+
+ fprintf(stderr, "%s not present in ne2k_pci\n", interface);
+ g_assert_not_reached();
}
-int main(int argc, char **argv)
+static void *ne2k_pci_create(void *pci_bus, QGuestAllocator *alloc, void *addr)
{
- int ret;
+ QNe2k_pci *ne2k_pci = g_new0(QNe2k_pci, 1);
+ QPCIBus *bus = pci_bus;
- g_test_init(&argc, &argv, NULL);
- qtest_add_func("/ne2000/pci/nop", pci_nop);
+ qpci_device_init(&ne2k_pci->dev, bus, addr);
+ ne2k_pci->obj.get_driver = ne2k_pci_get_driver;
- qtest_start("-device ne2k_pci");
- ret = g_test_run();
+ return &ne2k_pci->obj;
+}
- qtest_end();
+static void ne2000_register_nodes(void)
+{
+ QOSGraphEdgeOptions opts = {
+ .extra_device_opts = "addr=04.0",
+ };
+ add_qpci_address(&opts, &(QPCIAddress) { .devfn = QPCI_DEVFN(4, 0) });
- return ret;
+ qos_node_create_driver("ne2k_pci", ne2k_pci_create);
+ qos_node_consumes("ne2k_pci", "pci-bus", &opts);
+ qos_node_produces("ne2k_pci", "pci-device");
}
+
+libqos_init(ne2000_register_nodes);
diff --git a/tests/nvme-test.c b/tests/nvme-test.c
index 2700ba838a..b48d3a24b9 100644
--- a/tests/nvme-test.c
+++ b/tests/nvme-test.c
@@ -10,49 +10,47 @@
#include "qemu/osdep.h"
#include "qemu/units.h"
#include "libqtest.h"
-#include "libqos/libqos-pc.h"
+#include "libqos/qgraph.h"
+#include "libqos/pci.h"
-static QOSState *qnvme_start(const char *extra_opts)
+typedef struct QNvme QNvme;
+
+struct QNvme {
+ QOSGraphObject obj;
+ QPCIDevice dev;
+};
+
+static void *nvme_get_driver(void *obj, const char *interface)
{
- QOSState *qs;
- const char *arch = qtest_get_arch();
- const char *cmd = "-drive id=drv0,if=none,file=null-co://,format=raw "
- "-device nvme,addr=0x4.0,serial=foo,drive=drv0 %s";
-
- if (strcmp(arch, "i386") == 0 || strcmp(arch, "x86_64") == 0) {
- qs = qtest_pc_boot(cmd, extra_opts ? : "");
- global_qtest = qs->qts;
- return qs;
+ QNvme *nvme = obj;
+
+ if (!g_strcmp0(interface, "pci-device")) {
+ return &nvme->dev;
}
- g_printerr("nvme tests are only available on x86\n");
- exit(EXIT_FAILURE);
+ fprintf(stderr, "%s not present in nvme\n", interface);
+ g_assert_not_reached();
}
-static void qnvme_stop(QOSState *qs)
+static void *nvme_create(void *pci_bus, QGuestAllocator *alloc, void *addr)
{
- qtest_shutdown(qs);
-}
+ QNvme *nvme = g_new0(QNvme, 1);
+ QPCIBus *bus = pci_bus;
-static void nop(void)
-{
- QOSState *qs;
+ qpci_device_init(&nvme->dev, bus, addr);
+ nvme->obj.get_driver = nvme_get_driver;
- qs = qnvme_start(NULL);
- qnvme_stop(qs);
+ return &nvme->obj;
}
-static void nvmetest_cmb_test(void)
+/* This used to cause a NULL pointer dereference. */
+static void nvmetest_oob_cmb_test(void *obj, void *data, QGuestAllocator *alloc)
{
const int cmb_bar_size = 2 * MiB;
- QOSState *qs;
- QPCIDevice *pdev;
+ QNvme *nvme = obj;
+ QPCIDevice *pdev = &nvme->dev;
QPCIBar bar;
- qs = qnvme_start("-global nvme.cmb_size_mb=2");
- pdev = qpci_device_find(qs->pcibus, QPCI_DEVFN(4,0));
- g_assert(pdev != NULL);
-
qpci_device_enable(pdev);
bar = qpci_iomap(pdev, 2, NULL);
@@ -65,16 +63,24 @@ static void nvmetest_cmb_test(void)
g_assert_cmpint(qpci_io_readb(pdev, bar, cmb_bar_size - 1), ==, 0x11);
g_assert_cmpint(qpci_io_readw(pdev, bar, cmb_bar_size - 1), !=, 0x2211);
g_assert_cmpint(qpci_io_readl(pdev, bar, cmb_bar_size - 1), !=, 0x44332211);
- g_free(pdev);
-
- qnvme_stop(qs);
}
-int main(int argc, char **argv)
+static void nvme_register_nodes(void)
{
- g_test_init(&argc, &argv, NULL);
- qtest_add_func("/nvme/nop", nop);
- qtest_add_func("/nvme/cmb_test", nvmetest_cmb_test);
+ QOSGraphEdgeOptions opts = {
+ .extra_device_opts = "addr=04.0,drive=drv0,serial=foo",
+ .before_cmd_line = "-drive id=drv0,if=none,file=null-co://,format=raw",
+ };
+
+ add_qpci_address(&opts, &(QPCIAddress) { .devfn = QPCI_DEVFN(4, 0) });
- return g_test_run();
+ qos_node_create_driver("nvme", nvme_create);
+ qos_node_consumes("nvme", "pci-bus", &opts);
+ qos_node_produces("nvme", "pci-device");
+
+ qos_add_test("oob-cmb-access", "nvme", nvmetest_oob_cmb_test, &(QOSGraphTestOptions) {
+ .edge.extra_device_opts = "cmb_size_mb=2"
+ });
}
+
+libqos_init(nvme_register_nodes);
diff --git a/tests/pci-test.c b/tests/pci-test.c
new file mode 100644
index 0000000000..ff80985093
--- /dev/null
+++ b/tests/pci-test.c
@@ -0,0 +1,25 @@
+/*
+ * QTest testcase for PCI
+ *
+ * Copyright (c) 2018 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 "libqtest.h"
+#include "libqos/qgraph.h"
+#include "libqos/pci.h"
+
+/* Tests only initialization so far. TODO: Replace with functional tests */
+static void nop(void *obj, void *data, QGuestAllocator *alloc)
+{
+}
+
+static void register_pci_test(void)
+{
+ qos_add_test("nop", "pci-device", nop, NULL);
+}
+
+libqos_init(register_pci_test);
diff --git a/tests/pcnet-test.c b/tests/pcnet-test.c
index efb1ef44e9..484448cc64 100644
--- a/tests/pcnet-test.c
+++ b/tests/pcnet-test.c
@@ -9,23 +9,49 @@
#include "qemu/osdep.h"
#include "libqtest.h"
+#include "libqos/qgraph.h"
+#include "libqos/pci.h"
-/* Tests only initialization so far. TODO: Replace with functional tests */
-static void pci_nop(void)
+typedef struct QPCNet QPCNet;
+
+struct QPCNet {
+ QOSGraphObject obj;
+ QPCIDevice dev;
+};
+
+static void *pcnet_get_driver(void *obj, const char *interface)
{
+ QPCNet *pcnet = obj;
+
+ if (!g_strcmp0(interface, "pci-device")) {
+ return &pcnet->dev;
+ }
+
+ fprintf(stderr, "%s not present in pcnet\n", interface);
+ g_assert_not_reached();
}
-int main(int argc, char **argv)
+static void *pcnet_create(void *pci_bus, QGuestAllocator *alloc, void *addr)
{
- int ret;
+ QPCNet *pcnet = g_new0(QPCNet, 1);
+ QPCIBus *bus = pci_bus;
- g_test_init(&argc, &argv, NULL);
- qtest_add_func("/pcnet/pci/nop", pci_nop);
+ qpci_device_init(&pcnet->dev, bus, addr);
+ pcnet->obj.get_driver = pcnet_get_driver;
- qtest_start("-device pcnet");
- ret = g_test_run();
+ return &pcnet->obj;
+}
- qtest_end();
+static void pcnet_register_nodes(void)
+{
+ QOSGraphEdgeOptions opts = {
+ .extra_device_opts = "addr=04.0",
+ };
+ add_qpci_address(&opts, &(QPCIAddress) { .devfn = QPCI_DEVFN(4, 0) });
- return ret;
+ qos_node_create_driver("pcnet", pcnet_create);
+ qos_node_consumes("pcnet", "pci-bus", &opts);
+ qos_node_produces("pcnet", "pci-device");
}
+
+libqos_init(pcnet_register_nodes);
diff --git a/tests/q35-test.c b/tests/q35-test.c
index 7ea7acc9d8..34b34bc2b9 100644
--- a/tests/q35-test.c
+++ b/tests/q35-test.c
@@ -87,7 +87,7 @@ static void test_smram_lock(void)
qtest_start("-M q35");
- pcibus = qpci_init_pc(global_qtest, NULL);
+ pcibus = qpci_new_pc(global_qtest, NULL);
g_assert(pcibus != NULL);
pcidev = qpci_device_find(pcibus, 0);
@@ -146,7 +146,7 @@ static void test_tseg_size(const void *data)
g_free(cmdline);
/* locate the DRAM controller */
- pcibus = qpci_init_pc(global_qtest, NULL);
+ pcibus = qpci_new_pc(global_qtest, NULL);
g_assert(pcibus != NULL);
pcidev = qpci_device_find(pcibus, 0);
g_assert(pcidev != NULL);
diff --git a/tests/qos-test.c b/tests/qos-test.c
new file mode 100644
index 0000000000..6b1145eccc
--- /dev/null
+++ b/tests/qos-test.c
@@ -0,0 +1,445 @@
+/*
+ * libqos driver framework
+ *
+ * Copyright (c) 2018 Emanuele Giuseppe Esposito <e.emanuelegiuseppe@gmail.com>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2 as published by the Free Software Foundation.
+ *
+ * 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 <getopt.h>
+#include "qemu/osdep.h"
+#include "libqtest.h"
+#include "qapi/qmp/qdict.h"
+#include "qapi/qmp/qbool.h"
+#include "qapi/qmp/qstring.h"
+#include "qapi/qmp/qlist.h"
+#include "libqos/malloc.h"
+#include "libqos/qgraph.h"
+#include "libqos/qgraph_internal.h"
+
+static char *old_path;
+
+static void apply_to_node(const char *name, bool is_machine, bool is_abstract)
+{
+ char *machine_name = NULL;
+ if (is_machine) {
+ const char *arch = qtest_get_arch();
+ machine_name = g_strconcat(arch, "/", name, NULL);
+ name = machine_name;
+ }
+ qos_graph_node_set_availability(name, true);
+ if (is_abstract) {
+ qos_delete_cmd_line(name);
+ }
+ g_free(machine_name);
+}
+
+/**
+ * apply_to_qlist(): using QMP queries QEMU for a list of
+ * machines and devices available, and sets the respective node
+ * as true. If a node is found, also all its produced and contained
+ * child are marked available.
+ *
+ * See qos_graph_node_set_availability() for more info
+ */
+static void apply_to_qlist(QList *list, bool is_machine)
+{
+ const QListEntry *p;
+ const char *name;
+ bool abstract;
+ QDict *minfo;
+ QObject *qobj;
+ QString *qstr;
+ QBool *qbool;
+
+ for (p = qlist_first(list); p; p = qlist_next(p)) {
+ minfo = qobject_to(QDict, qlist_entry_obj(p));
+ qobj = qdict_get(minfo, "name");
+ qstr = qobject_to(QString, qobj);
+ name = qstring_get_str(qstr);
+
+ qobj = qdict_get(minfo, "abstract");
+ if (qobj) {
+ qbool = qobject_to(QBool, qobj);
+ abstract = qbool_get_bool(qbool);
+ } else {
+ abstract = false;
+ }
+
+ apply_to_node(name, is_machine, abstract);
+ qobj = qdict_get(minfo, "alias");
+ if (qobj) {
+ qstr = qobject_to(QString, qobj);
+ name = qstring_get_str(qstr);
+ apply_to_node(name, is_machine, abstract);
+ }
+ }
+}
+
+/**
+ * qos_set_machines_devices_available(): sets availability of qgraph
+ * machines and devices.
+ *
+ * This function firstly starts QEMU with "-machine none" option,
+ * and then executes the QMP protocol asking for the list of devices
+ * and machines available.
+ *
+ * for each of these items, it looks up the corresponding qgraph node,
+ * setting it as available. The list currently returns all devices that
+ * are either machines or QEDGE_CONSUMED_BY other nodes.
+ * Therefore, in order to mark all other nodes, it recursively sets
+ * all its QEDGE_CONTAINS and QEDGE_PRODUCES child as available too.
+ */
+static void qos_set_machines_devices_available(void)
+{
+ QDict *response;
+ QDict *args = qdict_new();
+ QList *list;
+
+ qtest_start("-machine none");
+ response = qmp("{ 'execute': 'query-machines' }");
+ list = qdict_get_qlist(response, "return");
+
+ apply_to_qlist(list, true);
+
+ qobject_unref(response);
+
+ qdict_put_bool(args, "abstract", true);
+ qdict_put_str(args, "implements", "device");
+
+ response = qmp("{'execute': 'qom-list-types',"
+ " 'arguments': %p }", args);
+ g_assert(qdict_haskey(response, "return"));
+ list = qdict_get_qlist(response, "return");
+
+ apply_to_qlist(list, false);
+
+ qtest_end();
+ qobject_unref(response);
+}
+
+static QGuestAllocator *get_machine_allocator(QOSGraphObject *obj)
+{
+ return obj->get_driver(obj, "memory");
+}
+
+static void restart_qemu_or_continue(char *path)
+{
+ /* compares the current command line with the
+ * one previously executed: if they are the same,
+ * don't restart QEMU, if they differ, stop previous
+ * QEMU subprocess (if active) and start over with
+ * the new command line
+ */
+ if (g_strcmp0(old_path, path)) {
+ qtest_end();
+ qos_invalidate_command_line();
+ old_path = g_strdup(path);
+ qtest_start(path);
+ } else { /* if cmd line is the same, reset the guest */
+ qobject_unref(qmp("{ 'execute': 'system_reset' }"));
+ qmp_eventwait("RESET");
+ }
+}
+
+void qos_invalidate_command_line(void)
+{
+ g_free(old_path);
+ old_path = NULL;
+}
+
+/**
+ * allocate_objects(): given an array of nodes @arg,
+ * walks the path invoking all constructors and
+ * passing the corresponding parameter in order to
+ * continue the objects allocation.
+ * Once the test is reached, return the object it consumes.
+ *
+ * Since the machine and QEDGE_CONSUMED_BY nodes allocate
+ * memory in the constructor, g_test_queue_destroy is used so
+ * that after execution they can be safely free'd. (The test's
+ * ->before callback is also welcome to use g_test_queue_destroy).
+ *
+ * Note: as specified in walk_path() too, @arg is an array of
+ * char *, where arg[0] is a pointer to the command line
+ * string that will be used to properly start QEMU when executing
+ * the test, and the remaining elements represent the actual objects
+ * that will be allocated.
+ */
+static void *allocate_objects(QTestState *qts, char **path, QGuestAllocator **p_alloc)
+{
+ int current = 0;
+ QGuestAllocator *alloc;
+ QOSGraphObject *parent = NULL;
+ QOSGraphEdge *edge;
+ QOSGraphNode *node;
+ void *edge_arg;
+ void *obj;
+
+ node = qos_graph_get_node(path[current]);
+ g_assert(node->type == QNODE_MACHINE);
+
+ obj = qos_machine_new(node, qts);
+ qos_object_queue_destroy(obj);
+
+ alloc = get_machine_allocator(obj);
+ if (p_alloc) {
+ *p_alloc = alloc;
+ }
+
+ for (;;) {
+ if (node->type != QNODE_INTERFACE) {
+ qos_object_start_hw(obj);
+ parent = obj;
+ }
+
+ /* follow edge and get object for next node constructor */
+ current++;
+ edge = qos_graph_get_edge(path[current - 1], path[current]);
+ node = qos_graph_get_node(path[current]);
+
+ if (node->type == QNODE_TEST) {
+ g_assert(qos_graph_edge_get_type(edge) == QEDGE_CONSUMED_BY);
+ return obj;
+ }
+
+ switch (qos_graph_edge_get_type(edge)) {
+ case QEDGE_PRODUCES:
+ obj = parent->get_driver(parent, path[current]);
+ break;
+
+ case QEDGE_CONSUMED_BY:
+ edge_arg = qos_graph_edge_get_arg(edge);
+ obj = qos_driver_new(node, obj, alloc, edge_arg);
+ qos_object_queue_destroy(obj);
+ break;
+
+ case QEDGE_CONTAINS:
+ obj = parent->get_device(parent, path[current]);
+ break;
+ }
+ }
+}
+
+/* The argument to run_one_test, which is the test function that is registered
+ * with GTest, is a vector of strings. The first item is the initial command
+ * line (before it is modified by the test's "before" function), the remaining
+ * items are node names forming the path to the test node.
+ */
+static char **current_path;
+
+const char *qos_get_current_command_line(void)
+{
+ return current_path[0];
+}
+
+void *qos_allocate_objects(QTestState *qts, QGuestAllocator **p_alloc)
+{
+ return allocate_objects(qts, current_path + 1, p_alloc);
+}
+
+/**
+ * run_one_test(): given an array of nodes @arg,
+ * walks the path invoking all constructors and
+ * passing the corresponding parameter in order to
+ * continue the objects allocation.
+ * Once the test is reached, its function is executed.
+ *
+ * Since the machine and QEDGE_CONSUMED_BY nodes allocate
+ * memory in the constructor, g_test_queue_destroy is used so
+ * that after execution they can be safely free'd. The test's
+ * ->before callback is also welcome to use g_test_queue_destroy.
+ *
+ * Note: as specified in walk_path() too, @arg is an array of
+ * char *, where arg[0] is a pointer to the command line
+ * string that will be used to properly start QEMU when executing
+ * the test, and the remaining elements represent the actual objects
+ * that will be allocated.
+ *
+ * The order of execution is the following:
+ * 1) @before test function as defined in the given QOSGraphTestOptions
+ * 2) start QEMU
+ * 3) call all nodes constructor and get_driver/get_device depending on edge,
+ * start the hardware (*_device_enable functions)
+ * 4) start test
+ */
+static void run_one_test(const void *arg)
+{
+ QOSGraphNode *test_node;
+ QGuestAllocator *alloc = NULL;
+ void *obj;
+ char **path = (char **) arg;
+ GString *cmd_line = g_string_new(path[0]);
+ void *test_arg;
+
+ /* Before test */
+ current_path = path;
+ test_node = qos_graph_get_node(path[(g_strv_length(path) - 1)]);
+ test_arg = test_node->u.test.arg;
+ if (test_node->u.test.before) {
+ test_arg = test_node->u.test.before(cmd_line, test_arg);
+ }
+
+ restart_qemu_or_continue(cmd_line->str);
+ g_string_free(cmd_line, true);
+
+ obj = qos_allocate_objects(global_qtest, &alloc);
+ test_node->u.test.function(obj, test_arg, alloc);
+}
+
+static void subprocess_run_one_test(const void *arg)
+{
+ const gchar *path = arg;
+ g_test_trap_subprocess(path, 0, 0);
+ g_test_trap_assert_passed();
+}
+
+/*
+ * in this function, 2 path will be built:
+ * path_str, a one-string path (ex "pc/i440FX-pcihost/...")
+ * path_vec, a string-array path (ex [0] = "pc", [1] = "i440FX-pcihost").
+ *
+ * path_str will be only used to build the test name, and won't need the
+ * architecture name at beginning, since it will be added by qtest_add_func().
+ *
+ * path_vec is used to allocate all constructors of the path nodes.
+ * Each name in this array except position 0 must correspond to a valid
+ * QOSGraphNode name.
+ * Position 0 is special, initially contains just the <machine> name of
+ * the node, (ex for "x86_64/pc" it will be "pc"), used to build the test
+ * path (see below). After it will contain the command line used to start
+ * qemu with all required devices.
+ *
+ * Note that the machine node name must be with format <arch>/<machine>
+ * (ex "x86_64/pc"), because it will identify the node "x86_64/pc"
+ * and start QEMU with "-M pc". For this reason,
+ * when building path_str, path_vec
+ * initially contains the <machine> at position 0 ("pc"),
+ * and the node name at position 1 (<arch>/<machine>)
+ * ("x86_64/pc"), followed by the rest of the nodes.
+ */
+static void walk_path(QOSGraphNode *orig_path, int len)
+{
+ QOSGraphNode *path;
+ QOSGraphEdge *edge;
+
+ /* etype set to QEDGE_CONSUMED_BY so that machine can add to the command line */
+ QOSEdgeType etype = QEDGE_CONSUMED_BY;
+
+ /* twice QOS_PATH_MAX_ELEMENT_SIZE since each edge can have its arg */
+ char **path_vec = g_new0(char *, (QOS_PATH_MAX_ELEMENT_SIZE * 2));
+ int path_vec_size = 0;
+
+ char *after_cmd = NULL, *before_cmd = NULL, *after_device = NULL;
+ char *node_name = orig_path->name, *path_str;
+
+ GString *cmd_line = g_string_new("");
+ GString *cmd_line2 = g_string_new("");
+
+ path = qos_graph_get_node(node_name); /* root */
+ node_name = qos_graph_edge_get_dest(path->path_edge); /* machine name */
+
+ path_vec[path_vec_size++] = node_name;
+ path_vec[path_vec_size++] = qos_get_machine_type(node_name);
+
+ for (;;) {
+ path = qos_graph_get_node(node_name);
+ if (!path->path_edge) {
+ break;
+ }
+
+ node_name = qos_graph_edge_get_dest(path->path_edge);
+
+ /* append node command line + previous edge command line */
+ if (path->command_line && etype == QEDGE_CONSUMED_BY) {
+ g_string_append(cmd_line, path->command_line);
+ if (after_device) {
+ g_string_append(cmd_line, after_device);
+ }
+ }
+
+ path_vec[path_vec_size++] = qos_graph_edge_get_name(path->path_edge);
+ /* detect if edge has command line args */
+ after_cmd = qos_graph_edge_get_after_cmd_line(path->path_edge);
+ after_device = qos_graph_edge_get_extra_device_opts(path->path_edge);
+ before_cmd = qos_graph_edge_get_before_cmd_line(path->path_edge);
+ edge = qos_graph_get_edge(path->name, node_name);
+ etype = qos_graph_edge_get_type(edge);
+
+ if (before_cmd) {
+ g_string_append(cmd_line, before_cmd);
+ }
+ if (after_cmd) {
+ g_string_append(cmd_line2, after_cmd);
+ }
+ }
+
+ path_vec[path_vec_size++] = NULL;
+ if (after_device) {
+ g_string_append(cmd_line, after_device);
+ }
+ g_string_append(cmd_line, cmd_line2->str);
+ g_string_free(cmd_line2, true);
+
+ /* here position 0 has <arch>/<machine>, position 1 has <machine>.
+ * The path must not have the <arch>, qtest_add_data_func adds it.
+ */
+ path_str = g_strjoinv("/", path_vec + 1);
+
+ /* put arch/machine in position 1 so run_one_test can do its work
+ * and add the command line at position 0.
+ */
+ path_vec[1] = path_vec[0];
+ path_vec[0] = g_string_free(cmd_line, false);
+
+ if (path->u.test.subprocess) {
+ gchar *subprocess_path = g_strdup_printf("/%s/%s/subprocess",
+ qtest_get_arch(), path_str);
+ qtest_add_data_func(path_str, subprocess_path, subprocess_run_one_test);
+ g_test_add_data_func(subprocess_path, path_vec, run_one_test);
+ } else {
+ qtest_add_data_func(path_str, path_vec, run_one_test);
+ }
+
+ g_free(path_str);
+}
+
+
+
+/**
+ * main(): heart of the qgraph framework.
+ *
+ * - Initializes the glib test framework
+ * - Creates the graph by invoking the various _init constructors
+ * - Starts QEMU to mark the available devices
+ * - Walks the graph, and each path is added to
+ * the glib test framework (walk_path)
+ * - Runs the tests, calling allocate_object() and allocating the
+ * machine/drivers/test objects
+ * - Cleans up everything
+ */
+int main(int argc, char **argv)
+{
+ g_test_init(&argc, &argv, NULL);
+ qos_graph_init();
+ module_call_init(MODULE_INIT_QOM);
+ module_call_init(MODULE_INIT_LIBQOS);
+ qos_set_machines_devices_available();
+
+ qos_graph_foreach_test_path(walk_path);
+ g_test_run();
+ qtest_end();
+ qos_graph_destroy();
+ g_free(old_path);
+ return 0;
+}
diff --git a/tests/rtas-test.c b/tests/rtas-test.c
index 009bda6d23..ee888676ed 100644
--- a/tests/rtas-test.c
+++ b/tests/rtas-test.c
@@ -17,7 +17,7 @@ static void test_rtas_get_time_of_day(void)
global_qtest = qs->qts;
t1 = time(NULL);
- ret = qrtas_get_time_of_day(qs->qts, qs->alloc, &tm, &ns);
+ ret = qrtas_get_time_of_day(qs->qts, &qs->alloc, &tm, &ns);
g_assert_cmpint(ret, ==, 0);
t2 = mktimegm(&tm);
g_assert(t2 - t1 < 5); /* 5 sec max to run the test */
diff --git a/tests/rtc-test.c b/tests/rtc-test.c
index d7a96cbd79..509be707e3 100644
--- a/tests/rtc-test.c
+++ b/tests/rtc-test.c
@@ -165,9 +165,9 @@ static void check_time(int wiggle)
t = (long)mktime(datep);
s = (long)mktime(&start);
if (t < s) {
- g_test_message("RTC is %ld second(s) behind wall-clock\n", (s - t));
+ g_test_message("RTC is %ld second(s) behind wall-clock", (s - t));
} else {
- g_test_message("RTC is %ld second(s) ahead of wall-clock\n", (t - s));
+ g_test_message("RTC is %ld second(s) ahead of wall-clock", (t - s));
}
g_assert_cmpint(ABS(t - s), <=, wiggle);
diff --git a/tests/rtl8139-test.c b/tests/rtl8139-test.c
index 68bfc42178..d6d0c24909 100644
--- a/tests/rtl8139-test.c
+++ b/tests/rtl8139-test.c
@@ -35,7 +35,7 @@ static QPCIDevice *get_device(void)
{
QPCIDevice *dev;
- pcibus = qpci_init_pc(global_qtest, NULL);
+ pcibus = qpci_new_pc(global_qtest, NULL);
qpci_device_foreach(pcibus, 0x10ec, 0x8139, save_fn, &dev);
g_assert(dev != NULL);
@@ -46,12 +46,12 @@ static QPCIDevice *get_device(void)
static unsigned __attribute__((unused)) in_##name(void) \
{ \
unsigned res = qpci_io_read##len(dev, dev_bar, (val)); \
- g_test_message("*%s -> %x\n", #name, res); \
+ g_test_message("*%s -> %x", #name, res); \
return res; \
} \
static void out_##name(unsigned v) \
{ \
- g_test_message("%x -> *%s\n", v, #name); \
+ g_test_message("%x -> *%s", v, #name); \
qpci_io_write##len(dev, dev_bar, (val), v); \
}
@@ -176,7 +176,7 @@ static void test_timer(void)
}
}
- g_test_message("Everythink is ok!\n");
+ g_test_message("Everythink is ok!");
}
diff --git a/tests/sdhci-test.c b/tests/sdhci-test.c
index 982f5ebbb2..2f177e569f 100644
--- a/tests/sdhci-test.c
+++ b/tests/sdhci-test.c
@@ -12,6 +12,8 @@
#include "libqtest.h"
#include "libqos/pci-pc.h"
#include "hw/pci/pci.h"
+#include "libqos/qgraph.h"
+#include "libqos/sdhci.h"
#define SDHC_CAPAB 0x40
FIELD(SDHC_CAPAB, BASECLKFREQ, 8, 8); /* since v2 */
@@ -20,99 +22,11 @@ FIELD(SDHC_CAPAB, SDR, 32, 3); /* since v3 */
FIELD(SDHC_CAPAB, DRIVER, 36, 3); /* since v3 */
#define SDHC_HCVER 0xFE
-static const struct sdhci_t {
- const char *arch, *machine;
- struct {
- uintptr_t addr;
- uint8_t version;
- uint8_t baseclock;
- struct {
- bool sdma;
- uint64_t reg;
- } capab;
- } sdhci;
- struct {
- uint16_t vendor_id, device_id;
- } pci;
-} models[] = {
- /* PC via PCI */
- { "x86_64", "pc",
- {-1, 2, 0, {1, 0x057834b4} },
- .pci = { PCI_VENDOR_ID_REDHAT, PCI_DEVICE_ID_REDHAT_SDHCI } },
-
- /* Exynos4210 */
- { "arm", "smdkc210",
- {0x12510000, 2, 0, {1, 0x5e80080} } },
-
- /* i.MX 6 */
- { "arm", "sabrelite",
- {0x02190000, 3, 0, {1, 0x057834b4} } },
-
- /* BCM2835 */
- { "arm", "raspi2",
- {0x3f300000, 3, 52, {0, 0x052134b4} } },
-
- /* Zynq-7000 */
- { "arm", "xilinx-zynq-a9", /* Datasheet: UG585 (v1.12.1) */
- {0xe0100000, 2, 0, {1, 0x69ec0080} } },
-
- /* ZynqMP */
- { "aarch64", "xlnx-zcu102", /* Datasheet: UG1085 (v1.7) */
- {0xff160000, 3, 0, {1, 0x280737ec6481} } },
-
-};
-
-typedef struct QSDHCI {
- struct {
- QPCIBus *bus;
- QPCIDevice *dev;
- } pci;
- union {
- QPCIBar mem_bar;
- uint64_t addr;
- };
-} QSDHCI;
-
-static uint16_t sdhci_readw(QSDHCI *s, uint32_t reg)
-{
- uint16_t val;
-
- if (s->pci.dev) {
- val = qpci_io_readw(s->pci.dev, s->mem_bar, reg);
- } else {
- val = qtest_readw(global_qtest, s->addr + reg);
- }
-
- return val;
-}
-
-static uint64_t sdhci_readq(QSDHCI *s, uint32_t reg)
-{
- uint64_t val;
-
- if (s->pci.dev) {
- val = qpci_io_readq(s->pci.dev, s->mem_bar, reg);
- } else {
- val = qtest_readq(global_qtest, s->addr + reg);
- }
-
- return val;
-}
-
-static void sdhci_writeq(QSDHCI *s, uint32_t reg, uint64_t val)
-{
- if (s->pci.dev) {
- qpci_io_writeq(s->pci.dev, s->mem_bar, reg, val);
- } else {
- qtest_writeq(global_qtest, s->addr + reg, val);
- }
-}
-
static void check_specs_version(QSDHCI *s, uint8_t version)
{
uint32_t v;
- v = sdhci_readw(s, SDHC_HCVER);
+ v = s->readw(s, SDHC_HCVER);
v &= 0xff;
v += 1;
g_assert_cmpuint(v, ==, version);
@@ -122,7 +36,7 @@ static void check_capab_capareg(QSDHCI *s, uint64_t expec_capab)
{
uint64_t capab;
- capab = sdhci_readq(s, SDHC_CAPAB);
+ capab = s->readq(s, SDHC_CAPAB);
g_assert_cmphex(capab, ==, expec_capab);
}
@@ -131,11 +45,11 @@ static void check_capab_readonly(QSDHCI *s)
const uint64_t vrand = 0x123456789abcdef;
uint64_t capab0, capab1;
- capab0 = sdhci_readq(s, SDHC_CAPAB);
+ capab0 = s->readq(s, SDHC_CAPAB);
g_assert_cmpuint(capab0, !=, vrand);
- sdhci_writeq(s, SDHC_CAPAB, vrand);
- capab1 = sdhci_readq(s, SDHC_CAPAB);
+ s->writeq(s, SDHC_CAPAB, vrand);
+ capab1 = s->readq(s, SDHC_CAPAB);
g_assert_cmpuint(capab1, !=, vrand);
g_assert_cmpuint(capab1, ==, capab0);
}
@@ -147,7 +61,7 @@ static void check_capab_baseclock(QSDHCI *s, uint8_t expec_freq)
if (!expec_freq) {
return;
}
- capab = sdhci_readq(s, SDHC_CAPAB);
+ capab = s->readq(s, SDHC_CAPAB);
capab_freq = FIELD_EX64(capab, SDHC_CAPAB, BASECLKFREQ);
g_assert_cmpuint(capab_freq, ==, expec_freq);
}
@@ -156,7 +70,7 @@ static void check_capab_sdma(QSDHCI *s, bool supported)
{
uint64_t capab, capab_sdma;
- capab = sdhci_readq(s, SDHC_CAPAB);
+ capab = s->readq(s, SDHC_CAPAB);
capab_sdma = FIELD_EX64(capab, SDHC_CAPAB, SDMA);
g_assert_cmpuint(capab_sdma, ==, supported);
}
@@ -167,7 +81,7 @@ static void check_capab_v3(QSDHCI *s, uint8_t version)
if (version < 3) {
/* before v3 those fields are RESERVED */
- capab = sdhci_readq(s, SDHC_CAPAB);
+ capab = s->readq(s, SDHC_CAPAB);
capab_v3 = FIELD_EX64(capab, SDHC_CAPAB, SDR);
g_assert_cmpuint(capab_v3, ==, 0);
capab_v3 = FIELD_EX64(capab, SDHC_CAPAB, DRIVER);
@@ -175,78 +89,21 @@ static void check_capab_v3(QSDHCI *s, uint8_t version)
}
}
-static QSDHCI *machine_start(const struct sdhci_t *test)
-{
- QSDHCI *s = g_new0(QSDHCI, 1);
-
- if (test->pci.vendor_id) {
- /* PCI */
- uint16_t vendor_id, device_id;
- uint64_t barsize;
-
- global_qtest = qtest_initf("-machine %s -device sdhci-pci",
- test->machine);
-
- s->pci.bus = qpci_init_pc(global_qtest, NULL);
-
- /* Find PCI device and verify it's the right one */
- s->pci.dev = qpci_device_find(s->pci.bus, QPCI_DEVFN(4, 0));
- g_assert_nonnull(s->pci.dev);
- vendor_id = qpci_config_readw(s->pci.dev, PCI_VENDOR_ID);
- device_id = qpci_config_readw(s->pci.dev, PCI_DEVICE_ID);
- g_assert(vendor_id == test->pci.vendor_id);
- g_assert(device_id == test->pci.device_id);
- s->mem_bar = qpci_iomap(s->pci.dev, 0, &barsize);
- qpci_device_enable(s->pci.dev);
- } else {
- /* SysBus */
- global_qtest = qtest_initf("-machine %s", test->machine);
- s->addr = test->sdhci.addr;
- }
-
- return s;
-}
-
-static void machine_stop(QSDHCI *s)
-{
- qpci_free_pc(s->pci.bus);
- g_free(s->pci.dev);
- qtest_quit(global_qtest);
- g_free(s);
-}
-
-static void test_machine(const void *data)
+static void test_registers(void *obj, void *data, QGuestAllocator *alloc)
{
- const struct sdhci_t *test = data;
- QSDHCI *s;
+ QSDHCI *s = obj;
- s = machine_start(test);
-
- check_specs_version(s, test->sdhci.version);
- check_capab_capareg(s, test->sdhci.capab.reg);
+ check_specs_version(s, s->props.version);
+ check_capab_capareg(s, s->props.capab.reg);
check_capab_readonly(s);
- check_capab_v3(s, test->sdhci.version);
- check_capab_sdma(s, test->sdhci.capab.sdma);
- check_capab_baseclock(s, test->sdhci.baseclock);
-
- machine_stop(s);
+ check_capab_v3(s, s->props.version);
+ check_capab_sdma(s, s->props.capab.sdma);
+ check_capab_baseclock(s, s->props.baseclock);
}
-int main(int argc, char *argv[])
+static void register_sdhci_test(void)
{
- const char *arch = qtest_get_arch();
- char *name;
- int i;
-
- g_test_init(&argc, &argv, NULL);
- for (i = 0; i < ARRAY_SIZE(models); i++) {
- if (strcmp(arch, models[i].arch)) {
- continue;
- }
- name = g_strdup_printf("sdhci/%s", models[i].machine);
- qtest_add_data_func(name, &models[i], test_machine);
- g_free(name);
- }
-
- return g_test_run();
+ qos_add_test("registers", "sdhci", test_registers, NULL);
}
+
+libqos_init(register_sdhci_test);
diff --git a/tests/spapr-phb-test.c b/tests/spapr-phb-test.c
index d3522ea093..39b5766710 100644
--- a/tests/spapr-phb-test.c
+++ b/tests/spapr-phb-test.c
@@ -7,29 +7,25 @@
* 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/osdep.h"
#include "libqtest.h"
+#include "libqos/qgraph.h"
-#define TYPE_SPAPR_PCI_HOST_BRIDGE "spapr-pci-host-bridge"
-
-/* Tests only initialization so far. TODO: Replace with functional tests */
-static void test_phb_device(void)
+/* Tests only initialization so far. TODO: Replace with functional tests,
+ * for example by producing pci-bus.
+ */
+static void test_phb_device(void *obj, void *data, QGuestAllocator *alloc)
{
}
-int main(int argc, char **argv)
+static void register_phb_test(void)
{
- int ret;
-
- g_test_init(&argc, &argv, NULL);
- qtest_add_func("/spapr-phb/device", test_phb_device);
-
- qtest_start("-device " TYPE_SPAPR_PCI_HOST_BRIDGE ",index=30");
-
- ret = g_test_run();
-
- qtest_end();
-
- return ret;
+ qos_add_test("spapr-phb-test", "ppc64/pseries",
+ test_phb_device, &(QOSGraphTestOptions) {
+ .edge.before_cmd_line = "-device spapr-pci-host-bridge"
+ ",index=30",
+ });
}
+
+libqos_init(register_phb_test);
diff --git a/tests/tco-test.c b/tests/tco-test.c
index 6bee9a37d3..f89a42cdcc 100644
--- a/tests/tco-test.c
+++ b/tests/tco-test.c
@@ -64,7 +64,7 @@ static void test_init(TestData *d)
global_qtest = qs;
qtest_irq_intercept_in(qs, "ioapic");
- d->bus = qpci_init_pc(qs, NULL);
+ d->bus = qpci_new_pc(qs, NULL);
d->dev = qpci_device_find(d->bus, QPCI_DEVFN(0x1f, 0x00));
g_assert(d->dev != NULL);
diff --git a/tests/test-aio-multithread.c b/tests/test-aio-multithread.c
index 6440d54ac3..d3144be7e0 100644
--- a/tests/test-aio-multithread.c
+++ b/tests/test-aio-multithread.c
@@ -178,7 +178,7 @@ static void test_multi_co_schedule(int seconds)
}
join_aio_contexts();
- g_test_message("scheduled %d, queued %d, retry %d, total %d\n",
+ g_test_message("scheduled %d, queued %d, retry %d, total %d",
count_other, count_here, count_retry,
count_here + count_other + count_retry);
}
@@ -242,7 +242,7 @@ static void test_multi_co_mutex(int threads, int seconds)
}
join_aio_contexts();
- g_test_message("%d iterations/second\n", counter / seconds);
+ g_test_message("%d iterations/second", counter / seconds);
g_assert_cmpint(counter, ==, atomic_counter);
}
@@ -361,7 +361,7 @@ static void test_multi_fair_mutex(int threads, int seconds)
}
join_aio_contexts();
- g_test_message("%d iterations/second\n", counter / seconds);
+ g_test_message("%d iterations/second", counter / seconds);
g_assert_cmpint(counter, ==, atomic_counter);
}
@@ -417,7 +417,7 @@ static void test_multi_mutex(int threads, int seconds)
}
join_aio_contexts();
- g_test_message("%d iterations/second\n", counter / seconds);
+ g_test_message("%d iterations/second", counter / seconds);
g_assert_cmpint(counter, ==, atomic_counter);
}
diff --git a/tests/test-char.c b/tests/test-char.c
index 63b4d3289d..de328380c1 100644
--- a/tests/test-char.c
+++ b/tests/test-char.c
@@ -1003,6 +1003,103 @@ static void char_socket_client_test(gconstpointer opaque)
g_free(optstr);
}
+static void
+count_closed_event(void *opaque, int event)
+{
+ int *count = opaque;
+ if (event == CHR_EVENT_CLOSED) {
+ (*count)++;
+ }
+}
+
+static void
+char_socket_discard_read(void *opaque, const uint8_t *buf, int size)
+{
+}
+
+static void char_socket_server_two_clients_test(gconstpointer opaque)
+{
+ SocketAddress *incoming_addr = (gpointer) opaque;
+ Chardev *chr;
+ CharBackend be = {0};
+ QObject *qaddr;
+ SocketAddress *addr;
+ Visitor *v;
+ char *optstr;
+ QemuOpts *opts;
+ QIOChannelSocket *ioc1, *ioc2;
+ int closed = 0;
+
+ g_setenv("QTEST_SILENT_ERRORS", "1", 1);
+ /*
+ * We rely on addr containing "nowait", otherwise
+ * qemu_chr_new() will block until a client connects. We
+ * can't spawn our client thread though, because until
+ * qemu_chr_new() returns we don't know what TCP port was
+ * allocated by the OS
+ */
+ optstr = char_socket_addr_to_opt_str(incoming_addr,
+ false,
+ NULL,
+ true);
+ opts = qemu_opts_parse_noisily(qemu_find_opts("chardev"),
+ optstr, true);
+ g_assert_nonnull(opts);
+ chr = qemu_chr_new_from_opts(opts, NULL, &error_abort);
+ qemu_opts_del(opts);
+ g_assert_nonnull(chr);
+ g_assert(!object_property_get_bool(OBJECT(chr), "connected", &error_abort));
+
+ qaddr = object_property_get_qobject(OBJECT(chr), "addr", &error_abort);
+ g_assert_nonnull(qaddr);
+
+ v = qobject_input_visitor_new(qaddr);
+ visit_type_SocketAddress(v, "addr", &addr, &error_abort);
+ visit_free(v);
+ qobject_unref(qaddr);
+
+ qemu_chr_fe_init(&be, chr, &error_abort);
+
+ qemu_chr_fe_set_handlers(&be, char_socket_can_read, char_socket_discard_read,
+ count_closed_event, NULL,
+ &closed, NULL, true);
+
+ ioc1 = qio_channel_socket_new();
+ qio_channel_socket_connect_sync(ioc1, addr, &error_abort);
+ qemu_chr_wait_connected(chr, &error_abort);
+
+ /* switch the chardev to another context */
+ GMainContext *ctx = g_main_context_new();
+ qemu_chr_fe_set_handlers(&be, char_socket_can_read, char_socket_discard_read,
+ count_closed_event, NULL,
+ &closed, ctx, true);
+
+ /* Start a second connection while the first is still connected.
+ * It will be placed in the listen() backlog, and connect() will
+ * succeed immediately.
+ */
+ ioc2 = qio_channel_socket_new();
+ qio_channel_socket_connect_sync(ioc2, addr, &error_abort);
+
+ object_unref(OBJECT(ioc1));
+ /* The two connections should now be processed serially. */
+ while (g_main_context_iteration(ctx, TRUE)) {
+ if (closed == 1 && ioc2) {
+ object_unref(OBJECT(ioc2));
+ ioc2 = NULL;
+ }
+ if (closed == 2) {
+ break;
+ }
+ }
+
+ qapi_free_SocketAddress(addr);
+ object_unparent(OBJECT(chr));
+ g_main_context_unref(ctx);
+ g_free(optstr);
+ g_unsetenv("QTEST_SILENT_ERRORS");
+}
+
#ifdef HAVE_CHARDEV_SERIAL
static void char_serial_test(void)
@@ -1342,12 +1439,15 @@ int main(int argc, char **argv)
SOCKET_SERVER_TEST(tcp, &tcpaddr);
SOCKET_CLIENT_TEST(tcp, &tcpaddr);
+ g_test_add_data_func("/char/socket/server/two-clients/tcp", &tcpaddr,
+ char_socket_server_two_clients_test);
#ifndef WIN32
SOCKET_SERVER_TEST(unix, &unixaddr);
SOCKET_CLIENT_TEST(unix, &unixaddr);
+ g_test_add_data_func("/char/socket/server/two-clients/unix", &unixaddr,
+ char_socket_server_two_clients_test);
#endif
-
g_test_add_func("/char/udp", char_udp_test);
#ifdef HAVE_CHARDEV_SERIAL
g_test_add_func("/char/serial", char_serial_test);
diff --git a/tests/test-coroutine.c b/tests/test-coroutine.c
index 28e79b3210..e946d93a65 100644
--- a/tests/test-coroutine.c
+++ b/tests/test-coroutine.c
@@ -369,7 +369,7 @@ static void perf_lifecycle(void)
}
duration = g_test_timer_elapsed();
- g_test_message("Lifecycle %u iterations: %f s\n", max, duration);
+ g_test_message("Lifecycle %u iterations: %f s", max, duration);
}
static void perf_nesting(void)
@@ -393,7 +393,7 @@ static void perf_nesting(void)
}
duration = g_test_timer_elapsed();
- g_test_message("Nesting %u iterations of %u depth each: %f s\n",
+ g_test_message("Nesting %u iterations of %u depth each: %f s",
maxcycles, maxnesting, duration);
}
@@ -426,8 +426,7 @@ static void perf_yield(void)
}
duration = g_test_timer_elapsed();
- g_test_message("Yield %u iterations: %f s\n",
- maxcycles, duration);
+ g_test_message("Yield %u iterations: %f s", maxcycles, duration);
}
static __attribute__((noinline)) void dummy(unsigned *i)
@@ -449,8 +448,7 @@ static void perf_baseline(void)
}
duration = g_test_timer_elapsed();
- g_test_message("Function call %u iterations: %f s\n",
- maxcycles, duration);
+ g_test_message("Function call %u iterations: %f s", maxcycles, duration);
}
static __attribute__((noinline)) void perf_cost_func(void *opaque)
diff --git a/tests/test-qgraph.c b/tests/test-qgraph.c
new file mode 100644
index 0000000000..f6a6565e31
--- /dev/null
+++ b/tests/test-qgraph.c
@@ -0,0 +1,434 @@
+/*
+ * libqos driver framework
+ *
+ * Copyright (c) 2018 Emanuele Giuseppe Esposito <e.emanuelegiuseppe@gmail.com>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2 as published by the Free Software Foundation.
+ *
+ * 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 "libqos/qgraph.h"
+#include "libqos/qgraph_internal.h"
+
+#define MACHINE_PC "x86_64/pc"
+#define MACHINE_RASPI2 "arm/raspi2"
+#define I440FX "i440FX-pcihost"
+#define PCIBUS_PC "pcibus-pc"
+#define SDHCI "sdhci"
+#define PCIBUS "pci-bus"
+#define SDHCI_PCI "sdhci-pci"
+#define SDHCI_MM "generic-sdhci"
+#define REGISTER_TEST "register-test"
+
+int npath;
+
+static void *machinefunct(QTestState *qts)
+{
+ return NULL;
+}
+
+static void *driverfunct(void *obj, QGuestAllocator *machine, void *arg)
+{
+ return NULL;
+}
+
+static void testfunct(void *obj, void *arg, QGuestAllocator *alloc)
+{
+ return;
+}
+
+static void check_interface(const char *interface)
+{
+ g_assert_cmpint(qos_graph_has_machine(interface), ==, FALSE);
+ g_assert_nonnull(qos_graph_get_node(interface));
+ g_assert_cmpint(qos_graph_has_node(interface), ==, TRUE);
+ g_assert_cmpint(qos_graph_get_node_type(interface), ==, QNODE_INTERFACE);
+ qos_graph_node_set_availability(interface, TRUE);
+ g_assert_cmpint(qos_graph_get_node_availability(interface), ==, TRUE);
+}
+
+static void check_machine(const char *machine)
+{
+ qos_node_create_machine(machine, machinefunct);
+ g_assert_nonnull(qos_graph_get_machine(machine));
+ g_assert_cmpint(qos_graph_has_machine(machine), ==, TRUE);
+ g_assert_nonnull(qos_graph_get_node(machine));
+ g_assert_cmpint(qos_graph_get_node_availability(machine), ==, FALSE);
+ qos_graph_node_set_availability(machine, TRUE);
+ g_assert_cmpint(qos_graph_get_node_availability(machine), ==, TRUE);
+ g_assert_cmpint(qos_graph_has_node(machine), ==, TRUE);
+ g_assert_cmpint(qos_graph_get_node_type(machine), ==, QNODE_MACHINE);
+}
+
+static void check_contains(const char *machine, const char *driver)
+{
+ QOSGraphEdge *edge;
+ qos_node_contains(machine, driver, NULL);
+
+ edge = qos_graph_get_edge(machine, driver);
+ g_assert_nonnull(edge);
+ g_assert_cmpint(qos_graph_edge_get_type(edge), ==, QEDGE_CONTAINS);
+ g_assert_cmpint(qos_graph_has_edge(machine, driver), ==, TRUE);
+}
+
+static void check_produces(const char *machine, const char *interface)
+{
+ QOSGraphEdge *edge;
+
+ qos_node_produces(machine, interface);
+ check_interface(interface);
+ edge = qos_graph_get_edge(machine, interface);
+ g_assert_nonnull(edge);
+ g_assert_cmpint(qos_graph_edge_get_type(edge), ==,
+ QEDGE_PRODUCES);
+ g_assert_cmpint(qos_graph_has_edge(machine, interface), ==, TRUE);
+}
+
+static void check_consumes(const char *driver, const char *interface)
+{
+ QOSGraphEdge *edge;
+
+ qos_node_consumes(driver, interface, NULL);
+ check_interface(interface);
+ edge = qos_graph_get_edge(interface, driver);
+ g_assert_nonnull(edge);
+ g_assert_cmpint(qos_graph_edge_get_type(edge), ==, QEDGE_CONSUMED_BY);
+ g_assert_cmpint(qos_graph_has_edge(interface, driver), ==, TRUE);
+}
+
+static void check_driver(const char *driver)
+{
+ qos_node_create_driver(driver, driverfunct);
+ g_assert_cmpint(qos_graph_has_machine(driver), ==, FALSE);
+ g_assert_nonnull(qos_graph_get_node(driver));
+ g_assert_cmpint(qos_graph_has_node(driver), ==, TRUE);
+ g_assert_cmpint(qos_graph_get_node_type(driver), ==, QNODE_DRIVER);
+ g_assert_cmpint(qos_graph_get_node_availability(driver), ==, FALSE);
+ qos_graph_node_set_availability(driver, TRUE);
+ g_assert_cmpint(qos_graph_get_node_availability(driver), ==, TRUE);
+}
+
+static void check_test(const char *test, const char *interface)
+{
+ QOSGraphEdge *edge;
+ const char *full_name = g_strdup_printf("%s-tests/%s", interface, test);
+
+ qos_add_test(test, interface, testfunct, NULL);
+ g_assert_cmpint(qos_graph_has_machine(test), ==, FALSE);
+ g_assert_cmpint(qos_graph_has_machine(full_name), ==, FALSE);
+ g_assert_nonnull(qos_graph_get_node(full_name));
+ g_assert_cmpint(qos_graph_has_node(full_name), ==, TRUE);
+ g_assert_cmpint(qos_graph_get_node_type(full_name), ==, QNODE_TEST);
+ edge = qos_graph_get_edge(interface, full_name);
+ g_assert_nonnull(edge);
+ g_assert_cmpint(qos_graph_edge_get_type(edge), ==,
+ QEDGE_CONSUMED_BY);
+ g_assert_cmpint(qos_graph_has_edge(interface, full_name), ==, TRUE);
+ g_assert_cmpint(qos_graph_get_node_availability(full_name), ==, TRUE);
+ qos_graph_node_set_availability(full_name, FALSE);
+ g_assert_cmpint(qos_graph_get_node_availability(full_name), ==, FALSE);
+}
+
+static void count_each_test(QOSGraphNode *path, int len)
+{
+ npath++;
+}
+
+static void check_leaf_discovered(int n)
+{
+ npath = 0;
+ qos_graph_foreach_test_path(count_each_test);
+ g_assert_cmpint(n, ==, npath);
+}
+
+/* G_Test functions */
+
+static void init_nop(void)
+{
+ qos_graph_init();
+ qos_graph_destroy();
+}
+
+static void test_machine(void)
+{
+ qos_graph_init();
+ check_machine(MACHINE_PC);
+ qos_graph_destroy();
+}
+
+static void test_contains(void)
+{
+ qos_graph_init();
+ check_contains(MACHINE_PC, I440FX);
+ g_assert_null(qos_graph_get_machine(MACHINE_PC));
+ g_assert_null(qos_graph_get_machine(I440FX));
+ g_assert_null(qos_graph_get_node(MACHINE_PC));
+ g_assert_null(qos_graph_get_node(I440FX));
+ qos_graph_destroy();
+}
+
+static void test_multiple_contains(void)
+{
+ qos_graph_init();
+ check_contains(MACHINE_PC, I440FX);
+ check_contains(MACHINE_PC, PCIBUS_PC);
+ qos_graph_destroy();
+}
+
+static void test_produces(void)
+{
+ qos_graph_init();
+ check_produces(MACHINE_PC, I440FX);
+ g_assert_null(qos_graph_get_machine(MACHINE_PC));
+ g_assert_null(qos_graph_get_machine(I440FX));
+ g_assert_null(qos_graph_get_node(MACHINE_PC));
+ g_assert_nonnull(qos_graph_get_node(I440FX));
+ qos_graph_destroy();
+}
+
+static void test_multiple_produces(void)
+{
+ qos_graph_init();
+ check_produces(MACHINE_PC, I440FX);
+ check_produces(MACHINE_PC, PCIBUS_PC);
+ qos_graph_destroy();
+}
+
+static void test_consumes(void)
+{
+ qos_graph_init();
+ check_consumes(I440FX, SDHCI);
+ g_assert_null(qos_graph_get_machine(I440FX));
+ g_assert_null(qos_graph_get_machine(SDHCI));
+ g_assert_null(qos_graph_get_node(I440FX));
+ g_assert_nonnull(qos_graph_get_node(SDHCI));
+ qos_graph_destroy();
+}
+
+static void test_multiple_consumes(void)
+{
+ qos_graph_init();
+ check_consumes(I440FX, SDHCI);
+ check_consumes(PCIBUS_PC, SDHCI);
+ qos_graph_destroy();
+}
+
+static void test_driver(void)
+{
+ qos_graph_init();
+ check_driver(I440FX);
+ qos_graph_destroy();
+}
+
+static void test_test(void)
+{
+ qos_graph_init();
+ check_test(REGISTER_TEST, SDHCI);
+ qos_graph_destroy();
+}
+
+static void test_machine_contains_driver(void)
+{
+ qos_graph_init();
+ check_machine(MACHINE_PC);
+ check_driver(I440FX);
+ check_contains(MACHINE_PC, I440FX);
+ qos_graph_destroy();
+}
+
+static void test_driver_contains_driver(void)
+{
+ qos_graph_init();
+ check_driver(PCIBUS_PC);
+ check_driver(I440FX);
+ check_contains(PCIBUS_PC, I440FX);
+ qos_graph_destroy();
+}
+
+static void test_machine_produces_interface(void)
+{
+ qos_graph_init();
+ check_machine(MACHINE_PC);
+ check_produces(MACHINE_PC, SDHCI);
+ qos_graph_destroy();
+}
+
+static void test_driver_produces_interface(void)
+{
+ qos_graph_init();
+ check_driver(I440FX);
+ check_produces(I440FX, SDHCI);
+ qos_graph_destroy();
+}
+
+static void test_machine_consumes_interface(void)
+{
+ qos_graph_init();
+ check_machine(MACHINE_PC);
+ check_consumes(MACHINE_PC, SDHCI);
+ qos_graph_destroy();
+}
+
+static void test_driver_consumes_interface(void)
+{
+ qos_graph_init();
+ check_driver(I440FX);
+ check_consumes(I440FX, SDHCI);
+ qos_graph_destroy();
+}
+
+static void test_test_consumes_interface(void)
+{
+ qos_graph_init();
+ check_test(REGISTER_TEST, SDHCI);
+ qos_graph_destroy();
+}
+
+static void test_full_sample(void)
+{
+ qos_graph_init();
+ check_machine(MACHINE_PC);
+ check_contains(MACHINE_PC, I440FX);
+ check_driver(I440FX);
+ check_driver(PCIBUS_PC);
+ check_contains(I440FX, PCIBUS_PC);
+ check_produces(PCIBUS_PC, PCIBUS);
+ check_driver(SDHCI_PCI);
+ qos_node_consumes(SDHCI_PCI, PCIBUS, NULL);
+ check_produces(SDHCI_PCI, SDHCI);
+ check_driver(SDHCI_MM);
+ check_produces(SDHCI_MM, SDHCI);
+ qos_add_test(REGISTER_TEST, SDHCI, testfunct, NULL);
+ check_leaf_discovered(1);
+ qos_print_graph();
+ qos_graph_destroy();
+}
+
+static void test_full_sample_raspi(void)
+{
+ qos_graph_init();
+ check_machine(MACHINE_PC);
+ check_contains(MACHINE_PC, I440FX);
+ check_driver(I440FX);
+ check_driver(PCIBUS_PC);
+ check_contains(I440FX, PCIBUS_PC);
+ check_produces(PCIBUS_PC, PCIBUS);
+ check_driver(SDHCI_PCI);
+ qos_node_consumes(SDHCI_PCI, PCIBUS, NULL);
+ check_produces(SDHCI_PCI, SDHCI);
+ check_machine(MACHINE_RASPI2);
+ check_contains(MACHINE_RASPI2, SDHCI_MM);
+ check_driver(SDHCI_MM);
+ check_produces(SDHCI_MM, SDHCI);
+ qos_add_test(REGISTER_TEST, SDHCI, testfunct, NULL);
+ qos_print_graph();
+ check_leaf_discovered(2);
+ qos_graph_destroy();
+}
+
+static void test_cycle(void)
+{
+ qos_graph_init();
+ check_machine(MACHINE_RASPI2);
+ check_driver("B");
+ check_driver("C");
+ check_driver("D");
+ check_contains(MACHINE_RASPI2, "B");
+ check_contains("B", "C");
+ check_contains("C", "D");
+ check_contains("D", MACHINE_RASPI2);
+ check_leaf_discovered(0);
+ qos_print_graph();
+ qos_graph_destroy();
+}
+
+static void test_two_test_same_interface(void)
+{
+ qos_graph_init();
+ check_machine(MACHINE_RASPI2);
+ check_produces(MACHINE_RASPI2, "B");
+ qos_add_test("C", "B", testfunct, NULL);
+ qos_add_test("D", "B", testfunct, NULL);
+ check_contains(MACHINE_RASPI2, "B");
+ check_leaf_discovered(4);
+ qos_print_graph();
+ qos_graph_destroy();
+}
+
+static void test_test_in_path(void)
+{
+ qos_graph_init();
+ check_machine(MACHINE_RASPI2);
+ check_produces(MACHINE_RASPI2, "B");
+ qos_add_test("C", "B", testfunct, NULL);
+ check_driver("D");
+ check_consumes("D", "B");
+ check_produces("D", "E");
+ qos_add_test("F", "E", testfunct, NULL);
+ check_leaf_discovered(2);
+ qos_print_graph();
+ qos_graph_destroy();
+}
+
+static void test_double_edge(void)
+{
+ qos_graph_init();
+ check_machine(MACHINE_RASPI2);
+ check_produces("B", "C");
+ qos_node_consumes("C", "B", NULL);
+ qos_add_test("D", "C", testfunct, NULL);
+ check_contains(MACHINE_RASPI2, "B");
+ qos_print_graph();
+ qos_graph_destroy();
+}
+
+int main(int argc, char **argv)
+{
+ g_test_init(&argc, &argv, NULL);
+ g_test_add_func("/qgraph/init_nop", init_nop);
+ g_test_add_func("/qgraph/test_machine", test_machine);
+ g_test_add_func("/qgraph/test_contains", test_contains);
+ g_test_add_func("/qgraph/test_multiple_contains", test_multiple_contains);
+ g_test_add_func("/qgraph/test_produces", test_produces);
+ g_test_add_func("/qgraph/test_multiple_produces", test_multiple_produces);
+ g_test_add_func("/qgraph/test_consumes", test_consumes);
+ g_test_add_func("/qgraph/test_multiple_consumes",
+ test_multiple_consumes);
+ g_test_add_func("/qgraph/test_driver", test_driver);
+ g_test_add_func("/qgraph/test_test", test_test);
+ g_test_add_func("/qgraph/test_machine_contains_driver",
+ test_machine_contains_driver);
+ g_test_add_func("/qgraph/test_driver_contains_driver",
+ test_driver_contains_driver);
+ g_test_add_func("/qgraph/test_machine_produces_interface",
+ test_machine_produces_interface);
+ g_test_add_func("/qgraph/test_driver_produces_interface",
+ test_driver_produces_interface);
+ g_test_add_func("/qgraph/test_machine_consumes_interface",
+ test_machine_consumes_interface);
+ g_test_add_func("/qgraph/test_driver_consumes_interface",
+ test_driver_consumes_interface);
+ g_test_add_func("/qgraph/test_test_consumes_interface",
+ test_test_consumes_interface);
+ g_test_add_func("/qgraph/test_full_sample", test_full_sample);
+ g_test_add_func("/qgraph/test_full_sample_raspi", test_full_sample_raspi);
+ g_test_add_func("/qgraph/test_cycle", test_cycle);
+ g_test_add_func("/qgraph/test_two_test_same_interface",
+ test_two_test_same_interface);
+ g_test_add_func("/qgraph/test_test_in_path", test_test_in_path);
+ g_test_add_func("/qgraph/test_double_edge", test_double_edge);
+
+ g_test_run();
+ return 0;
+}
diff --git a/tests/tpci200-test.c b/tests/tpci200-test.c
deleted file mode 100644
index 0321ec27ec..0000000000
--- a/tests/tpci200-test.c
+++ /dev/null
@@ -1,31 +0,0 @@
-/*
- * QTest testcase for tpci200 PCI-IndustryPack bridge
- *
- * Copyright (c) 2014 SUSE LINUX Products GmbH
- *
- * 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"
-
-/* Tests only initialization so far. TODO: Replace with functional tests */
-static void nop(void)
-{
-}
-
-int main(int argc, char **argv)
-{
- int ret;
-
- g_test_init(&argc, &argv, NULL);
- qtest_add_func("/tpci200/nop", nop);
-
- qtest_start("-device tpci200");
- ret = g_test_run();
-
- qtest_end();
-
- return ret;
-}
diff --git a/tests/usb-hcd-ehci-test.c b/tests/usb-hcd-ehci-test.c
index f28ea27f37..8bc3e44189 100644
--- a/tests/usb-hcd-ehci-test.c
+++ b/tests/usb-hcd-ehci-test.c
@@ -52,7 +52,7 @@ static void ehci_port_test(struct qhc *hc, int port, uint32_t expect)
static void test_init(void)
{
- pcibus = qpci_init_pc(global_qtest, NULL);
+ pcibus = qpci_new_pc(global_qtest, NULL);
g_assert(pcibus != NULL);
qusb_pci_init_one(pcibus, &uhci1, QPCI_DEVFN(0x1d, 0), 4);
diff --git a/tests/usb-hcd-ohci-test.c b/tests/usb-hcd-ohci-test.c
index 48ddbfd26d..98af02e898 100644
--- a/tests/usb-hcd-ohci-test.c
+++ b/tests/usb-hcd-ohci-test.c
@@ -10,30 +10,58 @@
#include "qemu/osdep.h"
#include "libqtest.h"
#include "libqos/usb.h"
+#include "libqos/qgraph.h"
+#include "libqos/pci.h"
+typedef struct QOHCI_PCI QOHCI_PCI;
-static void test_ohci_init(void)
-{
+struct QOHCI_PCI {
+ QOSGraphObject obj;
+ QPCIDevice dev;
+};
+static void test_ohci_hotplug(void *obj, void *data, QGuestAllocator *alloc)
+{
+ usb_test_hotplug("ohci", "1", NULL);
}
-static void test_ohci_hotplug(void)
+static void *ohci_pci_get_driver(void *obj, const char *interface)
{
- usb_test_hotplug("ohci", "1", NULL);
+ QOHCI_PCI *ohci_pci = obj;
+
+ if (!g_strcmp0(interface, "pci-device")) {
+ return &ohci_pci->dev;
+ }
+
+ fprintf(stderr, "%s not present in pci-ohci\n", interface);
+ g_assert_not_reached();
}
-int main(int argc, char **argv)
+static void *ohci_pci_create(void *pci_bus, QGuestAllocator *alloc, void *addr)
{
- int ret;
+ QOHCI_PCI *ohci_pci = g_new0(QOHCI_PCI, 1);
+ ohci_pci->obj.get_driver = ohci_pci_get_driver;
- g_test_init(&argc, &argv, NULL);
+ return &ohci_pci->obj;
+}
+
+static void ohci_pci_register_nodes(void)
+{
+ QOSGraphEdgeOptions opts = {
+ .extra_device_opts = "addr=04.0,id=ohci",
+ };
+ add_qpci_address(&opts, &(QPCIAddress) { .devfn = QPCI_DEVFN(4, 0) });
- qtest_add_func("/ohci/pci/init", test_ohci_init);
- qtest_add_func("/ohci/pci/hotplug", test_ohci_hotplug);
+ qos_node_create_driver("pci-ohci", ohci_pci_create);
+ qos_node_consumes("pci-ohci", "pci-bus", &opts);
+ qos_node_produces("pci-ohci", "pci-device");
+}
- qtest_start("-device pci-ohci,id=ohci");
- ret = g_test_run();
- qtest_end();
+libqos_init(ohci_pci_register_nodes);
- return ret;
+static void register_ohci_pci_test(void)
+{
+ qos_add_test("ohci_pci-test-hotplug", "pci-ohci", test_ohci_hotplug, NULL);
}
+
+libqos_init(register_ohci_pci_test);
diff --git a/tests/vhost-user-test.c b/tests/vhost-user-test.c
index 4cd0a97f13..0c965b3b1e 100644
--- a/tests/vhost-user-test.c
+++ b/tests/vhost-user-test.c
@@ -41,8 +41,7 @@
#define QEMU_CMD_MEMFD " -m %d -object memory-backend-memfd,id=mem,size=%dM," \
" -numa node,memdev=mem"
#define QEMU_CMD_CHR " -chardev socket,id=%s,path=%s%s"
-#define QEMU_CMD_NETDEV " -netdev vhost-user,id=net0,chardev=%s,vhostforce"
-#define QEMU_CMD_NET " -device virtio-net-pci,netdev=net0"
+#define QEMU_CMD_NETDEV " -netdev vhost-user,id=hs0,chardev=%s,vhostforce"
#define HUGETLBFS_MAGIC 0x958458f6
@@ -136,13 +135,9 @@ enum {
};
typedef struct TestServer {
- QPCIBus *bus;
- QVirtioPCIDevice *dev;
- QVirtQueue *vq[VHOST_MAX_VIRTQUEUES];
gchar *socket_path;
gchar *mig_path;
gchar *chr_name;
- const gchar *mem_path;
gchar *tmpfs;
CharBackend chr;
int fds_num;
@@ -158,9 +153,9 @@ typedef struct TestServer {
bool test_fail;
int test_flags;
int queues;
- QGuestAllocator *alloc;
} TestServer;
+static const char *init_hugepagefs(void);
static TestServer *test_server_new(const gchar *name);
static void test_server_free(TestServer *server);
static void test_server_listen(TestServer *server);
@@ -171,66 +166,28 @@ enum test_memfd {
TEST_MEMFD_NO,
};
-static char *get_qemu_cmd(TestServer *s,
- int mem, enum test_memfd memfd,
- const char *chr_opts, const char *extra)
+static void append_vhost_opts(TestServer *s, GString *cmd_line,
+ const char *chr_opts)
{
- if (memfd == TEST_MEMFD_AUTO && qemu_memfd_check(0)) {
- memfd = TEST_MEMFD_YES;
- }
-
- if (memfd == TEST_MEMFD_YES) {
- return g_strdup_printf(QEMU_CMD_MEMFD QEMU_CMD_CHR
- QEMU_CMD_NETDEV QEMU_CMD_NET "%s", mem, mem,
- s->chr_name, s->socket_path,
- chr_opts, s->chr_name, extra);
- } else {
- return g_strdup_printf(QEMU_CMD_MEM QEMU_CMD_CHR
- QEMU_CMD_NETDEV QEMU_CMD_NET "%s", mem, mem,
- s->mem_path, s->chr_name, s->socket_path,
- chr_opts, s->chr_name, extra);
- }
+ g_string_append_printf(cmd_line, QEMU_CMD_CHR QEMU_CMD_NETDEV,
+ s->chr_name, s->socket_path,
+ chr_opts, s->chr_name);
}
-static void init_virtio_dev(QTestState *qts, TestServer *s, uint32_t features_mask)
+static void append_mem_opts(TestServer *server, GString *cmd_line,
+ int size, enum test_memfd memfd)
{
- uint32_t features;
- int i;
-
- s->bus = qpci_init_pc(qts, NULL);
- g_assert_nonnull(s->bus);
-
- s->dev = qvirtio_pci_device_find(s->bus, VIRTIO_ID_NET);
- g_assert_nonnull(s->dev);
-
- qvirtio_pci_device_enable(s->dev);
- qvirtio_reset(&s->dev->vdev);
- qvirtio_set_acknowledge(&s->dev->vdev);
- qvirtio_set_driver(&s->dev->vdev);
-
- s->alloc = pc_alloc_init(qts);
-
- for (i = 0; i < s->queues * 2; i++) {
- s->vq[i] = qvirtqueue_setup(&s->dev->vdev, s->alloc, i);
+ if (memfd == TEST_MEMFD_AUTO) {
+ memfd = qemu_memfd_check(0) ? TEST_MEMFD_YES : TEST_MEMFD_NO;
}
- features = qvirtio_get_features(&s->dev->vdev);
- features = features & features_mask;
- qvirtio_set_features(&s->dev->vdev, features);
-
- qvirtio_set_driver_ok(&s->dev->vdev);
-}
-
-static void uninit_virtio_dev(TestServer *s)
-{
- int i;
+ if (memfd == TEST_MEMFD_YES) {
+ g_string_append_printf(cmd_line, QEMU_CMD_MEMFD, size, size);
+ } else {
+ const char *root = init_hugepagefs() ? : server->tmpfs;
- for (i = 0; i < s->queues * 2; i++) {
- qvirtqueue_cleanup(s->dev->vdev.bus, s->vq[i], s->alloc);
+ g_string_append_printf(cmd_line, QEMU_CMD_MEM, size, size, root);
}
- pc_alloc_uninit(s->alloc);
-
- qvirtio_pci_device_free(s->dev);
}
static bool wait_for_fds(TestServer *s)
@@ -337,7 +294,7 @@ static void chr_read(void *opaque, const uint8_t *buf, int size)
}
if (size != VHOST_USER_HDR_SIZE) {
- g_test_message("Wrong message size received %d\n", size);
+ g_test_message("Wrong message size received %d", size);
return;
}
@@ -348,7 +305,7 @@ static void chr_read(void *opaque, const uint8_t *buf, int 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",
+ g_test_message("Wrong message size received %d != %d",
size, msg.size);
return;
}
@@ -467,17 +424,21 @@ static void chr_read(void *opaque, const uint8_t *buf, int size)
static const char *init_hugepagefs(void)
{
#ifdef CONFIG_LINUX
+ static const char *hugepagefs;
const char *path = getenv("QTEST_HUGETLBFS_PATH");
struct statfs fs;
int ret;
+ if (hugepagefs) {
+ return hugepagefs;
+ }
if (!path) {
return NULL;
}
if (access(path, R_OK | W_OK | X_OK)) {
- g_test_message("access on path (%s): %s\n", path, strerror(errno));
- abort();
+ g_test_message("access on path (%s): %s", path, strerror(errno));
+ g_test_fail();
return NULL;
}
@@ -486,18 +447,19 @@ static const char *init_hugepagefs(void)
} while (ret != 0 && errno == EINTR);
if (ret != 0) {
- g_test_message("statfs on path (%s): %s\n", path, strerror(errno));
- abort();
+ g_test_message("statfs on path (%s): %s", path, strerror(errno));
+ g_test_fail();
return NULL;
}
if (fs.f_type != HUGETLBFS_MAGIC) {
- g_test_message("Warning: path not on HugeTLBFS: %s\n", path);
- abort();
+ g_test_message("Warning: path not on HugeTLBFS: %s", path);
+ g_test_fail();
return NULL;
}
- return path;
+ hugepagefs = path;
+ return hugepagefs;
#else
return NULL;
#endif
@@ -522,7 +484,6 @@ static TestServer *test_server_new(const gchar *name)
g_assert(tmpfs);
server->tmpfs = g_strdup(tmpfs);
- server->mem_path = init_hugepagefs() ? : server->tmpfs;
server->socket_path = g_strdup_printf("%s/%s.sock", tmpfs, name);
server->mig_path = g_strdup_printf("%s/%s.mig", tmpfs, name);
server->chr_name = g_strdup_printf("chr-%s", name);
@@ -588,6 +549,7 @@ static void test_server_free(TestServer *server)
g_test_message("unable to rmdir: path (%s): %s",
server->tmpfs, strerror(errno));
}
+ g_free(server->tmpfs);
qemu_chr_fe_deinit(&server->chr, true);
@@ -600,11 +562,11 @@ static void test_server_free(TestServer *server)
}
g_free(server->chr_name);
- g_assert(server->bus);
- qpci_free_pc(server->bus);
g_main_loop_unref(server->loop);
g_main_context_unref(server->context);
+ g_cond_clear(&server->data_cond);
+ g_mutex_clear(&server->data_mutex);
g_free(server);
}
@@ -695,70 +657,79 @@ GSourceFuncs test_migrate_source_funcs = {
.check = test_migrate_source_check,
};
-static void test_read_guest_mem(const void *arg)
+static void vhost_user_test_cleanup(void *s)
+{
+ TestServer *server = s;
+
+ qos_invalidate_command_line();
+ test_server_free(server);
+}
+
+static void *vhost_user_test_setup(GString *cmd_line, void *arg)
{
- enum test_memfd memfd = GPOINTER_TO_INT(arg);
- TestServer *server = NULL;
- char *qemu_cmd = NULL;
- QTestState *s = NULL;
+ TestServer *server = test_server_new("vhost-user-test");
+ test_server_listen(server);
+
+ append_mem_opts(server, cmd_line, 256, TEST_MEMFD_AUTO);
+ append_vhost_opts(server, cmd_line, "");
+
+ g_test_queue_destroy(vhost_user_test_cleanup, server);
+
+ return server;
+}
- server = test_server_new(memfd == TEST_MEMFD_YES ?
- "read-guest-memfd" : "read-guest-mem");
+static void *vhost_user_test_setup_memfd(GString *cmd_line, void *arg)
+{
+ TestServer *server = test_server_new("vhost-user-test");
test_server_listen(server);
- qemu_cmd = get_qemu_cmd(server, 512, memfd, "", "");
+ append_mem_opts(server, cmd_line, 256, TEST_MEMFD_YES);
+ append_vhost_opts(server, cmd_line, "");
+
+ g_test_queue_destroy(vhost_user_test_cleanup, server);
- s = qtest_start(qemu_cmd);
- g_free(qemu_cmd);
+ return server;
+}
- init_virtio_dev(global_qtest, server, 1u << VIRTIO_NET_F_MAC);
+static void test_read_guest_mem(void *obj, void *arg, QGuestAllocator *alloc)
+{
+ TestServer *server = arg;
if (!wait_for_fds(server)) {
- goto exit;
+ return;
}
read_guest_mem_server(global_qtest, server);
-
-exit:
- uninit_virtio_dev(server);
-
- qtest_quit(s);
- test_server_free(server);
}
-static void test_migrate(void)
+static void test_migrate(void *obj, void *arg, QGuestAllocator *alloc)
{
- TestServer *s = test_server_new("src");
+ TestServer *s = arg;
TestServer *dest = test_server_new("dest");
+ GString *dest_cmdline = g_string_new(qos_get_current_command_line());
char *uri = g_strdup_printf("%s%s", "unix:", dest->mig_path);
- QTestState *from, *to;
+ QTestState *to;
GSource *source;
- gchar *cmd, *tmp;
QDict *rsp;
guint8 *log;
guint64 size;
- test_server_listen(s);
- test_server_listen(dest);
-
- cmd = get_qemu_cmd(s, 2, TEST_MEMFD_AUTO, "", "");
- from = qtest_start(cmd);
- g_free(cmd);
-
- init_virtio_dev(from, s, 1u << VIRTIO_NET_F_MAC);
if (!wait_for_fds(s)) {
- goto exit;
+ return;
}
size = get_log_size(s);
- g_assert_cmpint(size, ==, (2 * 1024 * 1024) / (VHOST_LOG_PAGE * 8));
+ g_assert_cmpint(size, ==, (256 * 1024 * 1024) / (VHOST_LOG_PAGE * 8));
+
+ test_server_listen(dest);
+ g_string_append_printf(dest_cmdline, " -incoming %s", uri);
+ append_mem_opts(dest, dest_cmdline, 256, TEST_MEMFD_AUTO);
+ append_vhost_opts(dest, dest_cmdline, "");
+ to = qtest_init(dest_cmdline->str);
- tmp = g_strdup_printf(" -incoming %s", uri);
- cmd = get_qemu_cmd(dest, 2, TEST_MEMFD_AUTO, "", tmp);
- g_free(tmp);
- to = qtest_init(cmd);
- g_free(cmd);
- init_virtio_dev(to, dest, 1u << VIRTIO_NET_F_MAC);
+ /* This would be where you call qos_allocate_objects(to, NULL), if you want
+ * to talk to the QVirtioNet object on the destination.
+ */
source = g_source_new(&test_migrate_source_funcs,
sizeof(TestMigrateSource));
@@ -799,18 +770,11 @@ static void test_migrate(void)
g_assert(wait_for_fds(dest));
read_guest_mem_server(to, dest);
- uninit_virtio_dev(dest);
- qtest_quit(to);
-
g_source_destroy(source);
g_source_unref(source);
-exit:
- uninit_virtio_dev(s);
-
+ qtest_quit(to);
test_server_free(dest);
- qtest_quit(from);
- test_server_free(s);
g_free(uri);
}
@@ -858,20 +822,26 @@ connect_thread(gpointer data)
return NULL;
}
-static void test_reconnect_subprocess(void)
+static void *vhost_user_test_setup_reconnect(GString *cmd_line, void *arg)
{
TestServer *s = test_server_new("reconnect");
- GSource *src;
- char *cmd;
g_thread_new("connect", connect_thread, s);
- cmd = get_qemu_cmd(s, 2, TEST_MEMFD_AUTO, ",server", "");
- qtest_start(cmd);
- g_free(cmd);
+ append_mem_opts(s, cmd_line, 256, TEST_MEMFD_AUTO);
+ append_vhost_opts(s, cmd_line, ",server");
+
+ g_test_queue_destroy(vhost_user_test_cleanup, s);
+
+ return s;
+}
+
+static void test_reconnect(void *obj, void *arg, QGuestAllocator *alloc)
+{
+ TestServer *s = arg;
+ GSource *src;
- init_virtio_dev(global_qtest, s, 1u << VIRTIO_NET_F_MAC);
if (!wait_for_fds(s)) {
- goto exit;
+ return;
}
wait_for_rings_started(s, 2);
@@ -885,159 +855,111 @@ static void test_reconnect_subprocess(void)
g_source_unref(src);
g_assert(wait_for_fds(s));
wait_for_rings_started(s, 2);
-
-exit:
- uninit_virtio_dev(s);
-
- 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);
-}
-
-static void test_connect_fail_subprocess(void)
+static void *vhost_user_test_setup_connect_fail(GString *cmd_line, void *arg)
{
TestServer *s = test_server_new("connect-fail");
- char *cmd;
s->test_fail = true;
- g_thread_new("connect", connect_thread, s);
- cmd = get_qemu_cmd(s, 2, TEST_MEMFD_AUTO, ",server", "");
- qtest_start(cmd);
- g_free(cmd);
-
- init_virtio_dev(global_qtest, s, 1u << VIRTIO_NET_F_MAC);
- if (!wait_for_fds(s)) {
- goto exit;
- }
- wait_for_rings_started(s, 2);
-exit:
- uninit_virtio_dev(s);
+ g_thread_new("connect", connect_thread, s);
+ append_mem_opts(s, cmd_line, 256, TEST_MEMFD_AUTO);
+ append_vhost_opts(s, cmd_line, ",server");
- qtest_end();
- test_server_free(s);
-}
+ g_test_queue_destroy(vhost_user_test_cleanup, s);
-static void test_connect_fail(void)
-{
- gchar *path = g_strdup_printf("/%s/vhost-user/connect-fail/subprocess",
- qtest_get_arch());
- g_test_trap_subprocess(path, 0, 0);
- g_test_trap_assert_passed();
- g_free(path);
+ return s;
}
-static void test_flags_mismatch_subprocess(void)
+static void *vhost_user_test_setup_flags_mismatch(GString *cmd_line, void *arg)
{
TestServer *s = test_server_new("flags-mismatch");
- char *cmd;
s->test_flags = TEST_FLAGS_DISCONNECT;
- g_thread_new("connect", connect_thread, s);
- cmd = get_qemu_cmd(s, 2, TEST_MEMFD_AUTO, ",server", "");
- qtest_start(cmd);
- g_free(cmd);
- init_virtio_dev(global_qtest, s, 1u << VIRTIO_NET_F_MAC);
- if (!wait_for_fds(s)) {
- goto exit;
- }
- wait_for_rings_started(s, 2);
+ g_thread_new("connect", connect_thread, s);
+ append_mem_opts(s, cmd_line, 256, TEST_MEMFD_AUTO);
+ append_vhost_opts(s, cmd_line, ",server");
-exit:
- uninit_virtio_dev(s);
+ g_test_queue_destroy(vhost_user_test_cleanup, s);
- qtest_end();
- test_server_free(s);
+ return s;
}
-static void test_flags_mismatch(void)
+static void test_vhost_user_started(void *obj, void *arg, QGuestAllocator *alloc)
{
- gchar *path = g_strdup_printf("/%s/vhost-user/flags-mismatch/subprocess",
- qtest_get_arch());
- g_test_trap_subprocess(path, 0, 0);
- g_test_trap_assert_passed();
- g_free(path);
-}
+ TestServer *s = arg;
+ if (!wait_for_fds(s)) {
+ return;
+ }
+ wait_for_rings_started(s, 2);
+}
-static void test_multiqueue(void)
+static void *vhost_user_test_setup_multiqueue(GString *cmd_line, void *arg)
{
- TestServer *s = test_server_new("mq");
- char *cmd;
- uint32_t features_mask = ~(QVIRTIO_F_BAD_FEATURE |
- (1u << VIRTIO_RING_F_INDIRECT_DESC) |
- (1u << VIRTIO_RING_F_EVENT_IDX));
+ TestServer *s = vhost_user_test_setup(cmd_line, arg);
+
s->queues = 2;
- test_server_listen(s);
+ g_string_append_printf(cmd_line,
+ " -set netdev.hs0.queues=%d"
+ " -global virtio-net-pci.vectors=%d",
+ s->queues, s->queues * 2 + 2);
- if (qemu_memfd_check(0)) {
- cmd = g_strdup_printf(
- QEMU_CMD_MEMFD QEMU_CMD_CHR QEMU_CMD_NETDEV ",queues=%d "
- "-device virtio-net-pci,netdev=net0,mq=on,vectors=%d",
- 512, 512, s->chr_name,
- s->socket_path, "", s->chr_name,
- s->queues, s->queues * 2 + 2);
- } else {
- cmd = g_strdup_printf(
- QEMU_CMD_MEM QEMU_CMD_CHR QEMU_CMD_NETDEV ",queues=%d "
- "-device virtio-net-pci,netdev=net0,mq=on,vectors=%d",
- 512, 512, s->mem_path, s->chr_name,
- s->socket_path, "", s->chr_name,
- s->queues, s->queues * 2 + 2);
- }
- qtest_start(cmd);
- g_free(cmd);
+ return s;
+}
- init_virtio_dev(global_qtest, s, features_mask);
+static void test_multiqueue(void *obj, void *arg, QGuestAllocator *alloc)
+{
+ TestServer *s = arg;
wait_for_rings_started(s, s->queues * 2);
-
- uninit_virtio_dev(s);
-
- qtest_end();
-
- test_server_free(s);
}
-int main(int argc, char **argv)
+static void register_vhost_user_test(void)
{
- g_test_init(&argc, &argv, NULL);
+ QOSGraphTestOptions opts = {
+ .before = vhost_user_test_setup,
+ .subprocess = true,
+ };
- module_call_init(MODULE_INIT_QOM);
qemu_add_opts(&qemu_chardev_opts);
+ qos_add_test("vhost-user/read-guest-mem/memfile",
+ "virtio-net",
+ test_read_guest_mem, &opts);
+
if (qemu_memfd_check(0)) {
- qtest_add_data_func("/vhost-user/read-guest-mem/memfd",
- GINT_TO_POINTER(TEST_MEMFD_YES),
- test_read_guest_mem);
+ opts.before = vhost_user_test_setup_memfd;
+ qos_add_test("vhost-user/read-guest-mem/memfd",
+ "virtio-net",
+ test_read_guest_mem, &opts);
}
- qtest_add_data_func("/vhost-user/read-guest-mem/memfile",
- GINT_TO_POINTER(TEST_MEMFD_NO), test_read_guest_mem);
- qtest_add_func("/vhost-user/migrate", test_migrate);
- qtest_add_func("/vhost-user/multiqueue", test_multiqueue);
+
+ qos_add_test("vhost-user/migrate",
+ "virtio-net",
+ test_migrate, &opts);
/* keeps failing on build-system since Aug 15 2017 */
if (getenv("QTEST_VHOST_USER_FIXME")) {
- qtest_add_func("/vhost-user/reconnect/subprocess",
- test_reconnect_subprocess);
- qtest_add_func("/vhost-user/reconnect", test_reconnect);
- qtest_add_func("/vhost-user/connect-fail/subprocess",
- test_connect_fail_subprocess);
- qtest_add_func("/vhost-user/connect-fail", test_connect_fail);
- qtest_add_func("/vhost-user/flags-mismatch/subprocess",
- test_flags_mismatch_subprocess);
- qtest_add_func("/vhost-user/flags-mismatch", test_flags_mismatch);
+ opts.before = vhost_user_test_setup_reconnect;
+ qos_add_test("vhost-user/reconnect", "virtio-net",
+ test_reconnect, &opts);
+
+ opts.before = vhost_user_test_setup_connect_fail;
+ qos_add_test("vhost-user/connect-fail", "virtio-net",
+ test_vhost_user_started, &opts);
+
+ opts.before = vhost_user_test_setup_flags_mismatch;
+ qos_add_test("vhost-user/flags-mismatch", "virtio-net",
+ test_vhost_user_started, &opts);
}
- return g_test_run();
+ opts.before = vhost_user_test_setup_multiqueue;
+ opts.edge.extra_device_opts = "mq=on";
+ qos_add_test("vhost-user/multiqueue",
+ "virtio-net",
+ test_multiqueue, &opts);
}
+libqos_init(register_vhost_user_test);
diff --git a/tests/virtio-9p-test.c b/tests/virtio-9p-test.c
index a2b31085f6..16107ad280 100644
--- a/tests/virtio-9p-test.c
+++ b/tests/virtio-9p-test.c
@@ -9,101 +9,36 @@
#include "qemu/osdep.h"
#include "libqtest.h"
-#include "qemu-common.h"
-#include "libqos/libqos-pc.h"
-#include "libqos/libqos-spapr.h"
-#include "libqos/virtio.h"
-#include "libqos/virtio-pci.h"
-#include "standard-headers/linux/virtio_ids.h"
-#include "standard-headers/linux/virtio_pci.h"
#include "hw/9pfs/9p.h"
#include "hw/9pfs/9p-synth.h"
+#include "libqos/virtio-9p.h"
+#include "libqos/qgraph.h"
#define QVIRTIO_9P_TIMEOUT_US (10 * 1000 * 1000)
+static QGuestAllocator *alloc;
-static const char mount_tag[] = "qtest";
-
-typedef struct {
- QVirtioDevice *dev;
- QOSState *qs;
- QVirtQueue *vq;
-} QVirtIO9P;
-
-static QVirtIO9P *qvirtio_9p_start(const char *driver)
-{
- const char *arch = qtest_get_arch();
- const char *cmd = "-fsdev synth,id=fsdev0 "
- "-device %s,fsdev=fsdev0,mount_tag=%s";
- QVirtIO9P *v9p = g_new0(QVirtIO9P, 1);
-
- if (strcmp(arch, "i386") == 0 || strcmp(arch, "x86_64") == 0) {
- v9p->qs = qtest_pc_boot(cmd, driver, mount_tag);
- } else if (strcmp(arch, "ppc64") == 0) {
- v9p->qs = qtest_spapr_boot(cmd, driver, mount_tag);
- } else {
- g_printerr("virtio-9p tests are only available on x86 or ppc64\n");
- exit(EXIT_FAILURE);
- }
- global_qtest = v9p->qs->qts;
-
- return v9p;
-}
-
-static void qvirtio_9p_stop(QVirtIO9P *v9p)
-{
- qtest_shutdown(v9p->qs);
- g_free(v9p);
-}
-
-static QVirtIO9P *qvirtio_9p_pci_start(void)
-{
- QVirtIO9P *v9p = qvirtio_9p_start("virtio-9p-pci");
- QVirtioPCIDevice *dev = qvirtio_pci_device_find(v9p->qs->pcibus,
- VIRTIO_ID_9P);
- g_assert_nonnull(dev);
- g_assert_cmphex(dev->vdev.device_type, ==, VIRTIO_ID_9P);
- v9p->dev = (QVirtioDevice *) dev;
-
- qvirtio_pci_device_enable(dev);
- qvirtio_reset(v9p->dev);
- qvirtio_set_acknowledge(v9p->dev);
- qvirtio_set_driver(v9p->dev);
-
- v9p->vq = qvirtqueue_setup(v9p->dev, v9p->qs->alloc, 0);
-
- qvirtio_set_driver_ok(v9p->dev);
-
- return v9p;
-}
-
-static void qvirtio_9p_pci_stop(QVirtIO9P *v9p)
-{
- qvirtqueue_cleanup(v9p->dev->bus, v9p->vq, v9p->qs->alloc);
- qvirtio_pci_device_disable(container_of(v9p->dev, QVirtioPCIDevice, vdev));
- qvirtio_pci_device_free((QVirtioPCIDevice *)v9p->dev);
- qvirtio_9p_stop(v9p);
-}
-
-static void pci_config(QVirtIO9P *v9p)
+static void pci_config(void *obj, void *data, QGuestAllocator *t_alloc)
{
- size_t tag_len = qvirtio_config_readw(v9p->dev, 0);
+ QVirtio9P *v9p = obj;
+ alloc = t_alloc;
+ size_t tag_len = qvirtio_config_readw(v9p->vdev, 0);
char *tag;
int i;
- g_assert_cmpint(tag_len, ==, strlen(mount_tag));
+ g_assert_cmpint(tag_len, ==, strlen(MOUNT_TAG));
tag = g_malloc(tag_len);
for (i = 0; i < tag_len; i++) {
- tag[i] = qvirtio_config_readb(v9p->dev, i + 2);
+ tag[i] = qvirtio_config_readb(v9p->vdev, i + 2);
}
- g_assert_cmpmem(tag, tag_len, mount_tag, tag_len);
+ g_assert_cmpmem(tag, tag_len, MOUNT_TAG, tag_len);
g_free(tag);
}
#define P9_MAX_SIZE 4096 /* Max size of a T-message or R-message */
typedef struct {
- QVirtIO9P *v9p;
+ QVirtio9P *v9p;
uint16_t tag;
uint64_t t_msg;
uint32_t t_size;
@@ -206,7 +141,7 @@ static void v9fs_string_read(P9Req *req, uint16_t *len, char **string)
uint16_t tag;
} QEMU_PACKED P9Hdr;
-static P9Req *v9fs_req_init(QVirtIO9P *v9p, uint32_t size, uint8_t id,
+static P9Req *v9fs_req_init(QVirtio9P *v9p, uint32_t size, uint8_t id,
uint16_t tag)
{
P9Req *req = g_new0(P9Req, 1);
@@ -224,7 +159,7 @@ static P9Req *v9fs_req_init(QVirtIO9P *v9p, uint32_t size, uint8_t id,
req->v9p = v9p;
req->t_size = total_size;
- req->t_msg = guest_alloc(v9p->qs->alloc, req->t_size);
+ req->t_msg = guest_alloc(alloc, req->t_size);
v9fs_memwrite(req, &hdr, 7);
req->tag = tag;
return req;
@@ -232,13 +167,13 @@ static P9Req *v9fs_req_init(QVirtIO9P *v9p, uint32_t size, uint8_t id,
static void v9fs_req_send(P9Req *req)
{
- QVirtIO9P *v9p = req->v9p;
+ QVirtio9P *v9p = req->v9p;
- req->r_msg = guest_alloc(v9p->qs->alloc, P9_MAX_SIZE);
+ req->r_msg = guest_alloc(alloc, P9_MAX_SIZE);
req->free_head = qvirtqueue_add(v9p->vq, req->t_msg, req->t_size, false,
true);
qvirtqueue_add(v9p->vq, req->r_msg, P9_MAX_SIZE, true, false);
- qvirtqueue_kick(v9p->dev, v9p->vq, req->free_head);
+ qvirtqueue_kick(v9p->vdev, v9p->vq, req->free_head);
req->t_off = 0;
}
@@ -257,9 +192,9 @@ static const char *rmessage_name(uint8_t id)
static void v9fs_req_wait_for_reply(P9Req *req, uint32_t *len)
{
- QVirtIO9P *v9p = req->v9p;
+ QVirtio9P *v9p = req->v9p;
- qvirtio_wait_used_elem(v9p->dev, v9p->vq, req->free_head, len,
+ qvirtio_wait_used_elem(v9p->vdev, v9p->vq, req->free_head, len,
QVIRTIO_9P_TIMEOUT_US);
}
@@ -290,10 +225,8 @@ static void v9fs_req_recv(P9Req *req, uint8_t id)
static void v9fs_req_free(P9Req *req)
{
- QVirtIO9P *v9p = req->v9p;
-
- guest_free(v9p->qs->alloc, req->t_msg);
- guest_free(v9p->qs->alloc, req->r_msg);
+ guest_free(alloc, req->t_msg);
+ guest_free(alloc, req->r_msg);
g_free(req);
}
@@ -306,7 +239,7 @@ static void v9fs_rlerror(P9Req *req, uint32_t *err)
}
/* size[4] Tversion tag[2] msize[4] version[s] */
-static P9Req *v9fs_tversion(QVirtIO9P *v9p, uint32_t msize, const char *version,
+static P9Req *v9fs_tversion(QVirtio9P *v9p, uint32_t msize, const char *version,
uint16_t tag)
{
P9Req *req;
@@ -341,7 +274,7 @@ static void v9fs_rversion(P9Req *req, uint16_t *len, char **version)
}
/* size[4] Tattach tag[2] fid[4] afid[4] uname[s] aname[s] n_uname[4] */
-static P9Req *v9fs_tattach(QVirtIO9P *v9p, uint32_t fid, uint32_t n_uname,
+static P9Req *v9fs_tattach(QVirtio9P *v9p, uint32_t fid, uint32_t n_uname,
uint16_t tag)
{
const char *uname = ""; /* ignored by QEMU */
@@ -370,7 +303,7 @@ static void v9fs_rattach(P9Req *req, v9fs_qid *qid)
}
/* size[4] Twalk tag[2] fid[4] newfid[4] nwname[2] nwname*(wname[s]) */
-static P9Req *v9fs_twalk(QVirtIO9P *v9p, uint32_t fid, uint32_t newfid,
+static P9Req *v9fs_twalk(QVirtio9P *v9p, uint32_t fid, uint32_t newfid,
uint16_t nwname, char *const wnames[], uint16_t tag)
{
P9Req *req;
@@ -412,7 +345,7 @@ static void v9fs_rwalk(P9Req *req, uint16_t *nwqid, v9fs_qid **wqid)
}
/* size[4] Tlopen tag[2] fid[4] flags[4] */
-static P9Req *v9fs_tlopen(QVirtIO9P *v9p, uint32_t fid, uint32_t flags,
+static P9Req *v9fs_tlopen(QVirtio9P *v9p, uint32_t fid, uint32_t flags,
uint16_t tag)
{
P9Req *req;
@@ -440,7 +373,7 @@ static void v9fs_rlopen(P9Req *req, v9fs_qid *qid, uint32_t *iounit)
}
/* size[4] Twrite tag[2] fid[4] offset[8] count[4] data[count] */
-static P9Req *v9fs_twrite(QVirtIO9P *v9p, uint32_t fid, uint64_t offset,
+static P9Req *v9fs_twrite(QVirtio9P *v9p, uint32_t fid, uint64_t offset,
uint32_t count, const void *data, uint16_t tag)
{
P9Req *req;
@@ -468,7 +401,7 @@ static void v9fs_rwrite(P9Req *req, uint32_t *count)
}
/* size[4] Tflush tag[2] oldtag[2] */
-static P9Req *v9fs_tflush(QVirtIO9P *v9p, uint16_t oldtag, uint16_t tag)
+static P9Req *v9fs_tflush(QVirtio9P *v9p, uint16_t oldtag, uint16_t tag)
{
P9Req *req;
@@ -485,8 +418,10 @@ static void v9fs_rflush(P9Req *req)
v9fs_req_free(req);
}
-static void fs_version(QVirtIO9P *v9p)
+static void fs_version(void *obj, void *data, QGuestAllocator *t_alloc)
{
+ QVirtio9P *v9p = obj;
+ alloc = t_alloc;
const char *version = "9P2000.L";
uint16_t server_len;
char *server_version;
@@ -501,18 +436,22 @@ static void fs_version(QVirtIO9P *v9p)
g_free(server_version);
}
-static void fs_attach(QVirtIO9P *v9p)
+static void fs_attach(void *obj, void *data, QGuestAllocator *t_alloc)
{
+ QVirtio9P *v9p = obj;
+ alloc = t_alloc;
P9Req *req;
- fs_version(v9p);
+ fs_version(v9p, NULL, t_alloc);
req = v9fs_tattach(v9p, 0, getuid(), 0);
v9fs_req_wait_for_reply(req, NULL);
v9fs_rattach(req, NULL);
}
-static void fs_walk(QVirtIO9P *v9p)
+static void fs_walk(void *obj, void *data, QGuestAllocator *t_alloc)
{
+ QVirtio9P *v9p = obj;
+ alloc = t_alloc;
char *wnames[P9_MAXWELEM];
uint16_t nwqid;
v9fs_qid *wqid;
@@ -523,7 +462,7 @@ static void fs_walk(QVirtIO9P *v9p)
wnames[i] = g_strdup_printf(QTEST_V9FS_SYNTH_WALK_FILE, i);
}
- fs_attach(v9p);
+ fs_attach(v9p, NULL, t_alloc);
req = v9fs_twalk(v9p, 0, 1, P9_MAXWELEM, wnames, 0);
v9fs_req_wait_for_reply(req, NULL);
v9fs_rwalk(req, &nwqid, &wqid);
@@ -537,13 +476,15 @@ static void fs_walk(QVirtIO9P *v9p)
g_free(wqid);
}
-static void fs_walk_no_slash(QVirtIO9P *v9p)
+static void fs_walk_no_slash(void *obj, void *data, QGuestAllocator *t_alloc)
{
+ QVirtio9P *v9p = obj;
+ alloc = t_alloc;
char *const wnames[] = { g_strdup(" /") };
P9Req *req;
uint32_t err;
- fs_attach(v9p);
+ fs_attach(v9p, NULL, t_alloc);
req = v9fs_twalk(v9p, 0, 1, 1, wnames, 0);
v9fs_req_wait_for_reply(req, NULL);
v9fs_rlerror(req, &err);
@@ -553,13 +494,15 @@ static void fs_walk_no_slash(QVirtIO9P *v9p)
g_free(wnames[0]);
}
-static void fs_walk_dotdot(QVirtIO9P *v9p)
+static void fs_walk_dotdot(void *obj, void *data, QGuestAllocator *t_alloc)
{
+ QVirtio9P *v9p = obj;
+ alloc = t_alloc;
char *const wnames[] = { g_strdup("..") };
v9fs_qid root_qid, *wqid;
P9Req *req;
- fs_version(v9p);
+ fs_version(v9p, NULL, t_alloc);
req = v9fs_tattach(v9p, 0, getuid(), 0);
v9fs_req_wait_for_reply(req, NULL);
v9fs_rattach(req, &root_qid);
@@ -574,12 +517,14 @@ static void fs_walk_dotdot(QVirtIO9P *v9p)
g_free(wnames[0]);
}
-static void fs_lopen(QVirtIO9P *v9p)
+static void fs_lopen(void *obj, void *data, QGuestAllocator *t_alloc)
{
+ QVirtio9P *v9p = obj;
+ alloc = t_alloc;
char *const wnames[] = { g_strdup(QTEST_V9FS_SYNTH_LOPEN_FILE) };
P9Req *req;
- fs_attach(v9p);
+ fs_attach(v9p, NULL, t_alloc);
req = v9fs_twalk(v9p, 0, 1, 1, wnames, 0);
v9fs_req_wait_for_reply(req, NULL);
v9fs_rwalk(req, NULL, NULL);
@@ -591,15 +536,17 @@ static void fs_lopen(QVirtIO9P *v9p)
g_free(wnames[0]);
}
-static void fs_write(QVirtIO9P *v9p)
+static void fs_write(void *obj, void *data, QGuestAllocator *t_alloc)
{
+ QVirtio9P *v9p = obj;
+ alloc = t_alloc;
static const uint32_t write_count = P9_MAX_SIZE / 2;
char *const wnames[] = { g_strdup(QTEST_V9FS_SYNTH_WRITE_FILE) };
char *buf = g_malloc0(write_count);
uint32_t count;
P9Req *req;
- fs_attach(v9p);
+ fs_attach(v9p, NULL, t_alloc);
req = v9fs_twalk(v9p, 0, 1, 1, wnames, 0);
v9fs_req_wait_for_reply(req, NULL);
v9fs_rwalk(req, NULL, NULL);
@@ -617,14 +564,16 @@ static void fs_write(QVirtIO9P *v9p)
g_free(wnames[0]);
}
-static void fs_flush_success(QVirtIO9P *v9p)
+static void fs_flush_success(void *obj, void *data, QGuestAllocator *t_alloc)
{
+ QVirtio9P *v9p = obj;
+ alloc = t_alloc;
char *const wnames[] = { g_strdup(QTEST_V9FS_SYNTH_FLUSH_FILE) };
P9Req *req, *flush_req;
uint32_t reply_len;
uint8_t should_block;
- fs_attach(v9p);
+ fs_attach(v9p, NULL, t_alloc);
req = v9fs_twalk(v9p, 0, 1, 1, wnames, 0);
v9fs_req_wait_for_reply(req, NULL);
v9fs_rwalk(req, NULL, NULL);
@@ -652,14 +601,16 @@ static void fs_flush_success(QVirtIO9P *v9p)
g_free(wnames[0]);
}
-static void fs_flush_ignored(QVirtIO9P *v9p)
+static void fs_flush_ignored(void *obj, void *data, QGuestAllocator *t_alloc)
{
+ QVirtio9P *v9p = obj;
+ alloc = t_alloc;
char *const wnames[] = { g_strdup(QTEST_V9FS_SYNTH_FLUSH_FILE) };
P9Req *req, *flush_req;
uint32_t count;
uint8_t should_block;
- fs_attach(v9p);
+ fs_attach(v9p, NULL, t_alloc);
req = v9fs_twalk(v9p, 0, 1, 1, wnames, 0);
v9fs_req_wait_for_reply(req, NULL);
v9fs_rwalk(req, NULL, NULL);
@@ -687,39 +638,22 @@ static void fs_flush_ignored(QVirtIO9P *v9p)
g_free(wnames[0]);
}
-typedef void (*v9fs_test_fn)(QVirtIO9P *v9p);
-
-static void v9fs_run_pci_test(gconstpointer data)
+static void register_virtio_9p_test(void)
{
- v9fs_test_fn fn = data;
- QVirtIO9P *v9p = qvirtio_9p_pci_start();
-
- if (fn) {
- fn(v9p);
- }
- qvirtio_9p_pci_stop(v9p);
-}
-
-static void v9fs_qtest_pci_add(const char *path, v9fs_test_fn fn)
-{
- qtest_add_data_func(path, fn, v9fs_run_pci_test);
+ qos_add_test("config", "virtio-9p", pci_config, NULL);
+ qos_add_test("fs/version/basic", "virtio-9p", fs_version, NULL);
+ qos_add_test("fs/attach/basic", "virtio-9p", fs_attach, NULL);
+ qos_add_test("fs/walk/basic", "virtio-9p", fs_walk, NULL);
+ qos_add_test("fs/walk/no_slash", "virtio-9p", fs_walk_no_slash,
+ NULL);
+ qos_add_test("fs/walk/dotdot_from_root", "virtio-9p",
+ fs_walk_dotdot, NULL);
+ qos_add_test("fs/lopen/basic", "virtio-9p", fs_lopen, NULL);
+ qos_add_test("fs/write/basic", "virtio-9p", fs_write, NULL);
+ qos_add_test("fs/flush/success", "virtio-9p", fs_flush_success,
+ NULL);
+ qos_add_test("fs/flush/ignored", "virtio-9p", fs_flush_ignored,
+ NULL);
}
-int main(int argc, char **argv)
-{
- g_test_init(&argc, &argv, NULL);
- v9fs_qtest_pci_add("/virtio/9p/pci/nop", NULL);
- v9fs_qtest_pci_add("/virtio/9p/pci/config", pci_config);
- v9fs_qtest_pci_add("/virtio/9p/pci/fs/version/basic", fs_version);
- v9fs_qtest_pci_add("/virtio/9p/pci/fs/attach/basic", fs_attach);
- v9fs_qtest_pci_add("/virtio/9p/pci/fs/walk/basic", fs_walk);
- v9fs_qtest_pci_add("/virtio/9p/pci/fs/walk/no_slash", fs_walk_no_slash);
- v9fs_qtest_pci_add("/virtio/9p/pci/fs/walk/dotdot_from_root",
- fs_walk_dotdot);
- v9fs_qtest_pci_add("/virtio/9p/pci/fs/lopen/basic", fs_lopen);
- v9fs_qtest_pci_add("/virtio/9p/pci/fs/write/basic", fs_write);
- v9fs_qtest_pci_add("/virtio/9p/pci/fs/flush/success", fs_flush_success);
- v9fs_qtest_pci_add("/virtio/9p/pci/fs/flush/ignored", fs_flush_ignored);
-
- return g_test_run();
-}
+libqos_init(register_virtio_9p_test);
diff --git a/tests/virtio-balloon-test.c b/tests/virtio-balloon-test.c
deleted file mode 100644
index 5a1d0ccbb7..0000000000
--- a/tests/virtio-balloon-test.c
+++ /dev/null
@@ -1,33 +0,0 @@
-/*
- * QTest testcase for VirtIO Balloon
- *
- * Copyright (c) 2014 SUSE LINUX Products GmbH
- *
- * 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 "libqos/virtio.h"
-
-/* Tests only initialization so far. TODO: Replace with functional tests */
-static void balloon_nop(void)
-{
-}
-
-int main(int argc, char **argv)
-{
- int ret;
-
- g_test_init(&argc, &argv, NULL);
- qtest_add_func("/virtio/balloon/nop", balloon_nop);
-
- global_qtest = qtest_initf("-device virtio-balloon-%s",
- qvirtio_get_dev_type());
- ret = g_test_run();
-
- qtest_end();
-
- return ret;
-}
diff --git a/tests/virtio-blk-test.c b/tests/virtio-blk-test.c
index 8d2fc9c710..b02be0274e 100644
--- a/tests/virtio-blk-test.c
+++ b/tests/virtio-blk-test.c
@@ -10,19 +10,11 @@
#include "qemu/osdep.h"
#include "libqtest.h"
-#include "libqos/libqos-pc.h"
-#include "libqos/libqos-spapr.h"
-#include "libqos/virtio.h"
-#include "libqos/virtio-pci.h"
-#include "libqos/virtio-mmio.h"
-#include "libqos/malloc-generic.h"
-#include "qapi/qmp/qdict.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"
+#include "libqos/qgraph.h"
+#include "libqos/virtio-blk.h"
/* TODO actually test the results and get rid of this */
#define qmp_discard_response(...) qobject_unref(qmp(__VA_ARGS__))
@@ -30,13 +22,6 @@
#define TEST_IMAGE_SIZE (64 * 1024 * 1024)
#define QVIRTIO_BLK_TIMEOUT_US (30 * 1000 * 1000)
#define PCI_SLOT_HP 0x06
-#define PCI_SLOT 0x04
-#define PCI_FN 0x00
-
-#define MMIO_PAGE_SIZE 4096
-#define MMIO_DEV_BASE_ADDR 0x0A003E00
-#define MMIO_RAM_ADDR 0x40000000
-#define MMIO_RAM_SIZE 0x20000000
typedef struct QVirtioBlkReq {
uint32_t type;
@@ -46,87 +31,34 @@ typedef struct QVirtioBlkReq {
uint8_t status;
} QVirtioBlkReq;
+
#ifdef HOST_WORDS_BIGENDIAN
const bool host_is_big_endian = true;
#else
const bool host_is_big_endian; /* false */
#endif
+static void drive_destroy(void *path)
+{
+ unlink(path);
+ g_free(path);
+ qos_invalidate_command_line();
+}
+
static char *drive_create(void)
{
int fd, ret;
- char *tmp_path = g_strdup("/tmp/qtest.XXXXXX");
+ char *t_path = g_strdup("/tmp/qtest.XXXXXX");
/* Create a temporary raw image */
- fd = mkstemp(tmp_path);
+ fd = mkstemp(t_path);
g_assert_cmpint(fd, >=, 0);
ret = ftruncate(fd, TEST_IMAGE_SIZE);
g_assert_cmpint(ret, ==, 0);
close(fd);
- return tmp_path;
-}
-
-static QOSState *pci_test_start(void)
-{
- QOSState *qs;
- const char *arch = qtest_get_arch();
- char *tmp_path;
- const char *cmd = "-drive if=none,id=drive0,file=%s,format=raw "
- "-drive if=none,id=drive1,file=null-co://,format=raw "
- "-device virtio-blk-pci,id=drv0,drive=drive0,"
- "addr=%x.%x";
-
- tmp_path = drive_create();
-
- if (strcmp(arch, "i386") == 0 || strcmp(arch, "x86_64") == 0) {
- qs = qtest_pc_boot(cmd, tmp_path, PCI_SLOT, PCI_FN);
- } else if (strcmp(arch, "ppc64") == 0) {
- qs = qtest_spapr_boot(cmd, tmp_path, PCI_SLOT, PCI_FN);
- } else {
- g_printerr("virtio-blk tests are only available on x86 or ppc64\n");
- exit(EXIT_FAILURE);
- }
- global_qtest = qs->qts;
- unlink(tmp_path);
- g_free(tmp_path);
- return qs;
-}
-
-static void arm_test_start(void)
-{
- char *tmp_path;
-
- tmp_path = drive_create();
-
- global_qtest = qtest_initf("-machine virt "
- "-drive if=none,id=drive0,file=%s,format=raw "
- "-device virtio-blk-device,drive=drive0",
- tmp_path);
- unlink(tmp_path);
- g_free(tmp_path);
-}
-
-static void test_end(void)
-{
- qtest_end();
-}
-
-static QVirtioPCIDevice *virtio_blk_pci_init(QPCIBus *bus, int slot)
-{
- QVirtioPCIDevice *dev;
-
- dev = qvirtio_pci_device_find_slot(bus, VIRTIO_ID_BLOCK, slot);
- g_assert(dev != NULL);
- g_assert_cmphex(dev->vdev.device_type, ==, VIRTIO_ID_BLOCK);
- g_assert_cmphex(dev->pdev->devfn, ==, ((slot << 3) | PCI_FN));
-
- qvirtio_pci_device_enable(dev);
- qvirtio_reset(&dev->vdev);
- qvirtio_set_acknowledge(&dev->vdev);
- qvirtio_set_driver(&dev->vdev);
-
- return dev;
+ g_test_queue_destroy(drive_destroy, t_path);
+ return t_path;
}
static inline void virtio_blk_fix_request(QVirtioDevice *d, QVirtioBlkReq *req)
@@ -397,31 +329,21 @@ static void test_basic(QVirtioDevice *dev, QGuestAllocator *alloc,
}
}
-static void pci_basic(void)
+static void basic(void *obj, void *data, QGuestAllocator *t_alloc)
{
- QVirtioPCIDevice *dev;
- QOSState *qs;
- QVirtQueuePCI *vqpci;
-
- qs = pci_test_start();
- dev = virtio_blk_pci_init(qs->pcibus, PCI_SLOT);
-
- vqpci = (QVirtQueuePCI *)qvirtqueue_setup(&dev->vdev, qs->alloc, 0);
-
- test_basic(&dev->vdev, qs->alloc, &vqpci->vq);
+ QVirtioBlk *blk_if = obj;
+ QVirtQueue *vq;
+ vq = qvirtqueue_setup(blk_if->vdev, t_alloc, 0);
+ test_basic(blk_if->vdev, t_alloc, vq);
+ qvirtqueue_cleanup(blk_if->vdev->bus, vq, t_alloc);
- /* End test */
- qvirtqueue_cleanup(dev->vdev.bus, &vqpci->vq, qs->alloc);
- qvirtio_pci_device_disable(dev);
- qvirtio_pci_device_free(dev);
- qtest_shutdown(qs);
}
-static void pci_indirect(void)
+static void indirect(void *obj, void *u_data, QGuestAllocator *t_alloc)
{
- QVirtioPCIDevice *dev;
- QVirtQueuePCI *vqpci;
- QOSState *qs;
+ QVirtQueue *vq;
+ QVirtioBlk *blk_if = obj;
+ QVirtioDevice *dev = blk_if->vdev;
QVirtioBlkReq req;
QVRingIndirectDesc *indirect;
uint64_t req_addr;
@@ -431,22 +353,18 @@ static void pci_indirect(void)
uint8_t status;
char *data;
- qs = pci_test_start();
-
- dev = virtio_blk_pci_init(qs->pcibus, PCI_SLOT);
-
- capacity = qvirtio_config_readq(&dev->vdev, 0);
+ capacity = qvirtio_config_readq(dev, 0);
g_assert_cmpint(capacity, ==, TEST_IMAGE_SIZE / 512);
- features = qvirtio_get_features(&dev->vdev);
+ features = qvirtio_get_features(dev);
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));
- qvirtio_set_features(&dev->vdev, features);
+ qvirtio_set_features(dev, features);
- vqpci = (QVirtQueuePCI *)qvirtqueue_setup(&dev->vdev, qs->alloc, 0);
- qvirtio_set_driver_ok(&dev->vdev);
+ vq = qvirtqueue_setup(dev, t_alloc, 0);
+ qvirtio_set_driver_ok(dev);
/* Write request */
req.type = VIRTIO_BLK_T_OUT;
@@ -455,23 +373,23 @@ static void pci_indirect(void)
req.data = g_malloc0(512);
strcpy(req.data, "TEST");
- req_addr = virtio_blk_request(qs->alloc, &dev->vdev, &req, 512);
+ req_addr = virtio_blk_request(t_alloc, dev, &req, 512);
g_free(req.data);
- indirect = qvring_indirect_desc_setup(&dev->vdev, qs->alloc, 2);
+ indirect = qvring_indirect_desc_setup(dev, t_alloc, 2);
qvring_indirect_desc_add(indirect, req_addr, 528, false);
qvring_indirect_desc_add(indirect, req_addr + 528, 1, true);
- free_head = qvirtqueue_add_indirect(&vqpci->vq, indirect);
- qvirtqueue_kick(&dev->vdev, &vqpci->vq, free_head);
+ free_head = qvirtqueue_add_indirect(vq, indirect);
+ qvirtqueue_kick(dev, vq, free_head);
- qvirtio_wait_used_elem(&dev->vdev, &vqpci->vq, free_head, NULL,
+ qvirtio_wait_used_elem(dev, vq, free_head, NULL,
QVIRTIO_BLK_TIMEOUT_US);
status = readb(req_addr + 528);
g_assert_cmpint(status, ==, 0);
g_free(indirect);
- guest_free(qs->alloc, req_addr);
+ guest_free(t_alloc, req_addr);
/* Read request */
req.type = VIRTIO_BLK_T_IN;
@@ -480,17 +398,17 @@ static void pci_indirect(void)
req.data = g_malloc0(512);
strcpy(req.data, "TEST");
- req_addr = virtio_blk_request(qs->alloc, &dev->vdev, &req, 512);
+ req_addr = virtio_blk_request(t_alloc, dev, &req, 512);
g_free(req.data);
- indirect = qvring_indirect_desc_setup(&dev->vdev, qs->alloc, 2);
+ indirect = qvring_indirect_desc_setup(dev, t_alloc, 2);
qvring_indirect_desc_add(indirect, req_addr, 16, false);
qvring_indirect_desc_add(indirect, req_addr + 16, 513, true);
- free_head = qvirtqueue_add_indirect(&vqpci->vq, indirect);
- qvirtqueue_kick(&dev->vdev, &vqpci->vq, free_head);
+ free_head = qvirtqueue_add_indirect(vq, indirect);
+ qvirtqueue_kick(dev, vq, free_head);
- qvirtio_wait_used_elem(&dev->vdev, &vqpci->vq, free_head, NULL,
+ qvirtio_wait_used_elem(dev, vq, free_head, NULL,
QVIRTIO_BLK_TIMEOUT_US);
status = readb(req_addr + 528);
g_assert_cmpint(status, ==, 0);
@@ -501,50 +419,37 @@ static void pci_indirect(void)
g_free(data);
g_free(indirect);
- guest_free(qs->alloc, req_addr);
-
- /* End test */
- qvirtqueue_cleanup(dev->vdev.bus, &vqpci->vq, qs->alloc);
- qvirtio_pci_device_disable(dev);
- qvirtio_pci_device_free(dev);
- qtest_shutdown(qs);
+ guest_free(t_alloc, req_addr);
+ qvirtqueue_cleanup(dev->bus, vq, t_alloc);
}
-static void pci_config(void)
+static void config(void *obj, void *data, QGuestAllocator *t_alloc)
{
- QVirtioPCIDevice *dev;
- QOSState *qs;
+ QVirtioBlk *blk_if = obj;
+ QVirtioDevice *dev = blk_if->vdev;
int n_size = TEST_IMAGE_SIZE / 2;
uint64_t capacity;
- qs = pci_test_start();
-
- dev = virtio_blk_pci_init(qs->pcibus, PCI_SLOT);
-
- capacity = qvirtio_config_readq(&dev->vdev, 0);
+ capacity = qvirtio_config_readq(dev, 0);
g_assert_cmpint(capacity, ==, TEST_IMAGE_SIZE / 512);
- qvirtio_set_driver_ok(&dev->vdev);
+ qvirtio_set_driver_ok(dev);
qmp_discard_response("{ 'execute': 'block_resize', "
" 'arguments': { 'device': 'drive0', "
" 'size': %d } }", n_size);
- qvirtio_wait_config_isr(&dev->vdev, QVIRTIO_BLK_TIMEOUT_US);
+ qvirtio_wait_config_isr(dev, QVIRTIO_BLK_TIMEOUT_US);
- capacity = qvirtio_config_readq(&dev->vdev, 0);
+ capacity = qvirtio_config_readq(dev, 0);
g_assert_cmpint(capacity, ==, n_size / 512);
-
- qvirtio_pci_device_disable(dev);
- qvirtio_pci_device_free(dev);
-
- qtest_shutdown(qs);
}
-static void pci_msix(void)
+static void msix(void *obj, void *u_data, QGuestAllocator *t_alloc)
{
- QVirtioPCIDevice *dev;
- QOSState *qs;
- QVirtQueuePCI *vqpci;
+ QVirtQueue *vq;
+ QVirtioBlkPCI *blk = obj;
+ QVirtioPCIDevice *pdev = &blk->pci_vdev;
+ QVirtioDevice *dev = &pdev->vdev;
QVirtioBlkReq req;
int n_size = TEST_IMAGE_SIZE / 2;
uint64_t req_addr;
@@ -553,36 +458,38 @@ static void pci_msix(void)
uint32_t free_head;
uint8_t status;
char *data;
+ QOSGraphObject *blk_object = obj;
+ QPCIDevice *pci_dev = blk_object->get_driver(blk_object, "pci-device");
- qs = pci_test_start();
-
- dev = virtio_blk_pci_init(qs->pcibus, PCI_SLOT);
- qpci_msix_enable(dev->pdev);
+ if (qpci_check_buggy_msi(pci_dev)) {
+ return;
+ }
- qvirtio_pci_set_msix_configuration_vector(dev, qs->alloc, 0);
+ qpci_msix_enable(pdev->pdev);
+ qvirtio_pci_set_msix_configuration_vector(pdev, t_alloc, 0);
- capacity = qvirtio_config_readq(&dev->vdev, 0);
+ capacity = qvirtio_config_readq(dev, 0);
g_assert_cmpint(capacity, ==, TEST_IMAGE_SIZE / 512);
- features = qvirtio_get_features(&dev->vdev);
+ features = qvirtio_get_features(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_set_features(&dev->vdev, features);
+ qvirtio_set_features(dev, features);
- vqpci = (QVirtQueuePCI *)qvirtqueue_setup(&dev->vdev, qs->alloc, 0);
- qvirtqueue_pci_msix_setup(dev, vqpci, qs->alloc, 1);
+ vq = qvirtqueue_setup(dev, t_alloc, 0);
+ qvirtqueue_pci_msix_setup(pdev, (QVirtQueuePCI *)vq, t_alloc, 1);
- qvirtio_set_driver_ok(&dev->vdev);
+ qvirtio_set_driver_ok(dev);
qmp_discard_response("{ 'execute': 'block_resize', "
" 'arguments': { 'device': 'drive0', "
" 'size': %d } }", n_size);
- qvirtio_wait_config_isr(&dev->vdev, QVIRTIO_BLK_TIMEOUT_US);
+ qvirtio_wait_config_isr(dev, QVIRTIO_BLK_TIMEOUT_US);
- capacity = qvirtio_config_readq(&dev->vdev, 0);
+ capacity = qvirtio_config_readq(dev, 0);
g_assert_cmpint(capacity, ==, n_size / 512);
/* Write request */
@@ -592,22 +499,22 @@ static void pci_msix(void)
req.data = g_malloc0(512);
strcpy(req.data, "TEST");
- req_addr = virtio_blk_request(qs->alloc, &dev->vdev, &req, 512);
+ req_addr = virtio_blk_request(t_alloc, dev, &req, 512);
g_free(req.data);
- free_head = qvirtqueue_add(&vqpci->vq, req_addr, 16, false, true);
- qvirtqueue_add(&vqpci->vq, req_addr + 16, 512, false, true);
- qvirtqueue_add(&vqpci->vq, req_addr + 528, 1, true, false);
- qvirtqueue_kick(&dev->vdev, &vqpci->vq, free_head);
+ free_head = qvirtqueue_add(vq, req_addr, 16, false, true);
+ qvirtqueue_add(vq, req_addr + 16, 512, false, true);
+ qvirtqueue_add(vq, req_addr + 528, 1, true, false);
+ qvirtqueue_kick(dev, vq, free_head);
- qvirtio_wait_used_elem(&dev->vdev, &vqpci->vq, free_head, NULL,
+ qvirtio_wait_used_elem(dev, vq, free_head, NULL,
QVIRTIO_BLK_TIMEOUT_US);
status = readb(req_addr + 528);
g_assert_cmpint(status, ==, 0);
- guest_free(qs->alloc, req_addr);
+ guest_free(t_alloc, req_addr);
/* Read request */
req.type = VIRTIO_BLK_T_IN;
@@ -615,18 +522,18 @@ static void pci_msix(void)
req.sector = 0;
req.data = g_malloc0(512);
- req_addr = virtio_blk_request(qs->alloc, &dev->vdev, &req, 512);
+ req_addr = virtio_blk_request(t_alloc, dev, &req, 512);
g_free(req.data);
- free_head = qvirtqueue_add(&vqpci->vq, req_addr, 16, false, true);
- qvirtqueue_add(&vqpci->vq, req_addr + 16, 512, true, true);
- qvirtqueue_add(&vqpci->vq, req_addr + 528, 1, true, false);
+ free_head = qvirtqueue_add(vq, req_addr, 16, false, true);
+ qvirtqueue_add(vq, req_addr + 16, 512, true, true);
+ qvirtqueue_add(vq, req_addr + 528, 1, true, false);
- qvirtqueue_kick(&dev->vdev, &vqpci->vq, free_head);
+ qvirtqueue_kick(dev, vq, free_head);
- qvirtio_wait_used_elem(&dev->vdev, &vqpci->vq, free_head, NULL,
+ qvirtio_wait_used_elem(dev, vq, free_head, NULL,
QVIRTIO_BLK_TIMEOUT_US);
status = readb(req_addr + 528);
@@ -637,21 +544,19 @@ static void pci_msix(void)
g_assert_cmpstr(data, ==, "TEST");
g_free(data);
- guest_free(qs->alloc, req_addr);
+ guest_free(t_alloc, req_addr);
/* End test */
- qvirtqueue_cleanup(dev->vdev.bus, &vqpci->vq, qs->alloc);
- qpci_msix_disable(dev->pdev);
- qvirtio_pci_device_disable(dev);
- qvirtio_pci_device_free(dev);
- qtest_shutdown(qs);
+ qpci_msix_disable(pdev->pdev);
+ qvirtqueue_cleanup(dev->bus, vq, t_alloc);
}
-static void pci_idx(void)
+static void idx(void *obj, void *u_data, QGuestAllocator *t_alloc)
{
- QVirtioPCIDevice *dev;
- QOSState *qs;
- QVirtQueuePCI *vqpci;
+ QVirtQueue *vq;
+ QVirtioBlkPCI *blk = obj;
+ QVirtioPCIDevice *pdev = &blk->pci_vdev;
+ QVirtioDevice *dev = &pdev->vdev;
QVirtioBlkReq req;
uint64_t req_addr;
uint64_t capacity;
@@ -661,28 +566,30 @@ static void pci_idx(void)
uint32_t desc_idx;
uint8_t status;
char *data;
+ QOSGraphObject *blk_object = obj;
+ QPCIDevice *pci_dev = blk_object->get_driver(blk_object, "pci-device");
- qs = pci_test_start();
-
- dev = virtio_blk_pci_init(qs->pcibus, PCI_SLOT);
- qpci_msix_enable(dev->pdev);
+ if (qpci_check_buggy_msi(pci_dev)) {
+ return;
+ }
- qvirtio_pci_set_msix_configuration_vector(dev, qs->alloc, 0);
+ qpci_msix_enable(pdev->pdev);
+ qvirtio_pci_set_msix_configuration_vector(pdev, t_alloc, 0);
- capacity = qvirtio_config_readq(&dev->vdev, 0);
+ capacity = qvirtio_config_readq(dev, 0);
g_assert_cmpint(capacity, ==, TEST_IMAGE_SIZE / 512);
- features = qvirtio_get_features(&dev->vdev);
+ features = qvirtio_get_features(dev);
features = features & ~(QVIRTIO_F_BAD_FEATURE |
(1u << VIRTIO_RING_F_INDIRECT_DESC) |
(1u << VIRTIO_F_NOTIFY_ON_EMPTY) |
(1u << VIRTIO_BLK_F_SCSI));
- qvirtio_set_features(&dev->vdev, features);
+ qvirtio_set_features(dev, features);
- vqpci = (QVirtQueuePCI *)qvirtqueue_setup(&dev->vdev, qs->alloc, 0);
- qvirtqueue_pci_msix_setup(dev, vqpci, qs->alloc, 1);
+ vq = qvirtqueue_setup(dev, t_alloc, 0);
+ qvirtqueue_pci_msix_setup(pdev, (QVirtQueuePCI *)vq, t_alloc, 1);
- qvirtio_set_driver_ok(&dev->vdev);
+ qvirtio_set_driver_ok(dev);
/* Write request */
req.type = VIRTIO_BLK_T_OUT;
@@ -691,16 +598,16 @@ static void pci_idx(void)
req.data = g_malloc0(512);
strcpy(req.data, "TEST");
- req_addr = virtio_blk_request(qs->alloc, &dev->vdev, &req, 512);
+ req_addr = virtio_blk_request(t_alloc, dev, &req, 512);
g_free(req.data);
- free_head = qvirtqueue_add(&vqpci->vq, req_addr, 16, false, true);
- qvirtqueue_add(&vqpci->vq, req_addr + 16, 512, false, true);
- qvirtqueue_add(&vqpci->vq, req_addr + 528, 1, true, false);
- qvirtqueue_kick(&dev->vdev, &vqpci->vq, free_head);
+ free_head = qvirtqueue_add(vq, req_addr, 16, false, true);
+ qvirtqueue_add(vq, req_addr + 16, 512, false, true);
+ qvirtqueue_add(vq, req_addr + 528, 1, true, false);
+ qvirtqueue_kick(dev, vq, free_head);
- qvirtio_wait_used_elem(&dev->vdev, &vqpci->vq, free_head, NULL,
+ qvirtio_wait_used_elem(dev, vq, free_head, NULL,
QVIRTIO_BLK_TIMEOUT_US);
/* Write request */
@@ -710,25 +617,25 @@ static void pci_idx(void)
req.data = g_malloc0(512);
strcpy(req.data, "TEST");
- req_addr = virtio_blk_request(qs->alloc, &dev->vdev, &req, 512);
+ req_addr = virtio_blk_request(t_alloc, dev, &req, 512);
g_free(req.data);
/* Notify after processing the third request */
- qvirtqueue_set_used_event(&vqpci->vq, 2);
- free_head = qvirtqueue_add(&vqpci->vq, req_addr, 16, false, true);
- qvirtqueue_add(&vqpci->vq, req_addr + 16, 512, false, true);
- qvirtqueue_add(&vqpci->vq, req_addr + 528, 1, true, false);
- qvirtqueue_kick(&dev->vdev, &vqpci->vq, free_head);
+ qvirtqueue_set_used_event(vq, 2);
+ free_head = qvirtqueue_add(vq, req_addr, 16, false, true);
+ qvirtqueue_add(vq, req_addr + 16, 512, false, true);
+ qvirtqueue_add(vq, req_addr + 528, 1, true, false);
+ qvirtqueue_kick(dev, vq, free_head);
write_head = free_head;
/* No notification expected */
- status = qvirtio_wait_status_byte_no_isr(&dev->vdev,
- &vqpci->vq, req_addr + 528,
+ status = qvirtio_wait_status_byte_no_isr(dev,
+ vq, req_addr + 528,
QVIRTIO_BLK_TIMEOUT_US);
g_assert_cmpint(status, ==, 0);
- guest_free(qs->alloc, req_addr);
+ guest_free(t_alloc, req_addr);
/* Read request */
req.type = VIRTIO_BLK_T_IN;
@@ -736,20 +643,20 @@ static void pci_idx(void)
req.sector = 1;
req.data = g_malloc0(512);
- req_addr = virtio_blk_request(qs->alloc, &dev->vdev, &req, 512);
+ req_addr = virtio_blk_request(t_alloc, dev, &req, 512);
g_free(req.data);
- free_head = qvirtqueue_add(&vqpci->vq, req_addr, 16, false, true);
- qvirtqueue_add(&vqpci->vq, req_addr + 16, 512, true, true);
- qvirtqueue_add(&vqpci->vq, req_addr + 528, 1, true, false);
+ free_head = qvirtqueue_add(vq, req_addr, 16, false, true);
+ qvirtqueue_add(vq, req_addr + 16, 512, true, true);
+ qvirtqueue_add(vq, req_addr + 528, 1, true, false);
- qvirtqueue_kick(&dev->vdev, &vqpci->vq, free_head);
+ qvirtqueue_kick(dev, vq, free_head);
/* We get just one notification for both requests */
- qvirtio_wait_used_elem(&dev->vdev, &vqpci->vq, write_head, NULL,
+ qvirtio_wait_used_elem(dev, vq, write_head, NULL,
QVIRTIO_BLK_TIMEOUT_US);
- g_assert(qvirtqueue_get_buf(&vqpci->vq, &desc_idx, NULL));
+ g_assert(qvirtqueue_get_buf(vq, &desc_idx, NULL));
g_assert_cmpint(desc_idx, ==, free_head);
status = readb(req_addr + 528);
@@ -760,124 +667,114 @@ static void pci_idx(void)
g_assert_cmpstr(data, ==, "TEST");
g_free(data);
- guest_free(qs->alloc, req_addr);
+ guest_free(t_alloc, req_addr);
/* End test */
- qvirtqueue_cleanup(dev->vdev.bus, &vqpci->vq, qs->alloc);
- qpci_msix_disable(dev->pdev);
- qvirtio_pci_device_disable(dev);
- qvirtio_pci_device_free(dev);
- qtest_shutdown(qs);
+ qpci_msix_disable(pdev->pdev);
+
+ qvirtqueue_cleanup(dev->bus, vq, t_alloc);
}
-static void pci_hotplug(void)
+static void pci_hotplug(void *obj, void *data, QGuestAllocator *t_alloc)
{
+ QVirtioPCIDevice *dev1 = obj;
QVirtioPCIDevice *dev;
- QOSState *qs;
- const char *arch = qtest_get_arch();
-
- qs = pci_test_start();
/* plug secondary disk */
qtest_qmp_device_add("virtio-blk-pci", "drv1",
"{'addr': %s, 'drive': 'drive1'}",
- stringify(PCI_SLOT_HP));
+ stringify(PCI_SLOT_HP) ".0");
- dev = virtio_blk_pci_init(qs->pcibus, PCI_SLOT_HP);
- g_assert(dev);
+ dev = virtio_pci_new(dev1->pdev->bus,
+ &(QPCIAddress) { .devfn = QPCI_DEVFN(PCI_SLOT_HP, 0) });
+ g_assert_nonnull(dev);
+ g_assert_cmpint(dev->vdev.device_type, ==, VIRTIO_ID_BLOCK);
qvirtio_pci_device_disable(dev);
- qvirtio_pci_device_free(dev);
+ qos_object_destroy((QOSGraphObject *)dev);
/* unplug secondary disk */
- if (strcmp(arch, "i386") == 0 || strcmp(arch, "x86_64") == 0) {
- qpci_unplug_acpi_device_test("drv1", PCI_SLOT_HP);
- }
- qtest_shutdown(qs);
+ qpci_unplug_acpi_device_test("drv1", PCI_SLOT_HP);
}
/*
* Check that setting the vring addr on a non-existent virtqueue does
* not crash.
*/
-static void test_nonexistent_virtqueue(void)
+static void test_nonexistent_virtqueue(void *obj, void *data,
+ QGuestAllocator *t_alloc)
{
+ QVirtioBlkPCI *blk = obj;
+ QVirtioPCIDevice *pdev = &blk->pci_vdev;
QPCIBar bar0;
- QOSState *qs;
QPCIDevice *dev;
- qs = pci_test_start();
- dev = qpci_device_find(qs->pcibus, QPCI_DEVFN(4, 0));
+ dev = qpci_device_find(pdev->pdev->bus, QPCI_DEVFN(4, 0));
g_assert(dev != NULL);
-
qpci_device_enable(dev);
+
bar0 = qpci_iomap(dev, 0, NULL);
qpci_io_writeb(dev, bar0, VIRTIO_PCI_QUEUE_SEL, 2);
qpci_io_writel(dev, bar0, VIRTIO_PCI_QUEUE_PFN, 1);
+
g_free(dev);
- qtest_shutdown(qs);
}
-static void mmio_basic(void)
+static void resize(void *obj, void *data, QGuestAllocator *t_alloc)
{
- QVirtioMMIODevice *dev;
- QVirtQueue *vq;
- QGuestAllocator *alloc;
+ QVirtioBlk *blk_if = obj;
+ QVirtioDevice *dev = blk_if->vdev;
int n_size = TEST_IMAGE_SIZE / 2;
uint64_t capacity;
+ QVirtQueue *vq;
- arm_test_start();
-
- 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);
-
- qvirtio_reset(&dev->vdev);
- qvirtio_set_acknowledge(&dev->vdev);
- qvirtio_set_driver(&dev->vdev);
-
- alloc = generic_alloc_init(MMIO_RAM_ADDR, MMIO_RAM_SIZE, MMIO_PAGE_SIZE);
- vq = qvirtqueue_setup(&dev->vdev, alloc, 0);
+ vq = qvirtqueue_setup(dev, t_alloc, 0);
- test_basic(&dev->vdev, alloc, vq);
+ test_basic(dev, t_alloc, vq);
qmp_discard_response("{ 'execute': 'block_resize', "
" 'arguments': { 'device': 'drive0', "
" 'size': %d } }", n_size);
- qvirtio_wait_queue_isr(&dev->vdev, vq, QVIRTIO_BLK_TIMEOUT_US);
+ qvirtio_wait_queue_isr(dev, vq, QVIRTIO_BLK_TIMEOUT_US);
- capacity = qvirtio_config_readq(&dev->vdev, 0);
+ capacity = qvirtio_config_readq(dev, 0);
g_assert_cmpint(capacity, ==, n_size / 512);
- /* End test */
- qvirtqueue_cleanup(dev->vdev.bus, vq, alloc);
- g_free(dev);
- generic_alloc_uninit(alloc);
- test_end();
+ qvirtqueue_cleanup(dev->bus, vq, t_alloc);
+
}
-int main(int argc, char **argv)
+static void *virtio_blk_test_setup(GString *cmd_line, void *arg)
{
- const char *arch = qtest_get_arch();
-
- g_test_init(&argc, &argv, NULL);
-
- if (strcmp(arch, "i386") == 0 || strcmp(arch, "x86_64") == 0 ||
- strcmp(arch, "ppc64") == 0) {
- qtest_add_func("/virtio/blk/pci/basic", pci_basic);
- qtest_add_func("/virtio/blk/pci/indirect", pci_indirect);
- qtest_add_func("/virtio/blk/pci/config", pci_config);
- qtest_add_func("/virtio/blk/pci/nxvirtq", test_nonexistent_virtqueue);
- if (strcmp(arch, "i386") == 0 || strcmp(arch, "x86_64") == 0) {
- qtest_add_func("/virtio/blk/pci/msix", pci_msix);
- qtest_add_func("/virtio/blk/pci/idx", pci_idx);
- }
- qtest_add_func("/virtio/blk/pci/hotplug", pci_hotplug);
- } else if (strcmp(arch, "arm") == 0) {
- qtest_add_func("/virtio/blk/mmio/basic", mmio_basic);
- }
+ char *tmp_path = drive_create();
- return g_test_run();
+ g_string_append_printf(cmd_line,
+ " -drive if=none,id=drive0,file=%s,format=raw "
+ "-drive if=none,id=drive1,file=null-co://,format=raw ",
+ tmp_path);
+
+ return arg;
}
+
+static void register_virtio_blk_test(void)
+{
+ QOSGraphTestOptions opts = {
+ .before = virtio_blk_test_setup,
+ };
+
+ qos_add_test("indirect", "virtio-blk", indirect, &opts);
+ qos_add_test("config", "virtio-blk", config, &opts);
+ qos_add_test("basic", "virtio-blk", basic, &opts);
+ qos_add_test("resize", "virtio-blk", resize, &opts);
+
+ /* tests just for virtio-blk-pci */
+ qos_add_test("msix", "virtio-blk-pci", msix, &opts);
+ qos_add_test("idx", "virtio-blk-pci", idx, &opts);
+ qos_add_test("nxvirtq", "virtio-blk-pci",
+ test_nonexistent_virtqueue, &opts);
+ qos_add_test("hotplug", "virtio-blk-pci", pci_hotplug, &opts);
+}
+
+libqos_init(register_virtio_blk_test);
diff --git a/tests/virtio-console-test.c b/tests/virtio-console-test.c
deleted file mode 100644
index a7c6f167c3..0000000000
--- a/tests/virtio-console-test.c
+++ /dev/null
@@ -1,38 +0,0 @@
-/*
- * QTest testcase for VirtIO Console
- *
- * Copyright (c) 2014 SUSE LINUX Products GmbH
- *
- * 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 "libqos/virtio.h"
-
-/* Tests only initialization so far. TODO: Replace with functional tests */
-static void console_nop(void)
-{
- global_qtest = qtest_initf("-device virtio-serial-%s,id=vser0 "
- "-device virtconsole,bus=vser0.0",
- qvirtio_get_dev_type());
- qtest_end();
-}
-
-static void serialport_nop(void)
-{
- global_qtest = qtest_initf("-device virtio-serial-%s,id=vser0 "
- "-device virtserialport,bus=vser0.0",
- qvirtio_get_dev_type());
- qtest_end();
-}
-
-int main(int argc, char **argv)
-{
- g_test_init(&argc, &argv, NULL);
- qtest_add_func("/virtio/console/nop", console_nop);
- qtest_add_func("/virtio/serialport/nop", serialport_nop);
-
- return g_test_run();
-}
diff --git a/tests/virtio-net-test.c b/tests/virtio-net-test.c
index e9783e6707..c58e670e2f 100644
--- a/tests/virtio-net-test.c
+++ b/tests/virtio-net-test.c
@@ -9,18 +9,11 @@
#include "qemu/osdep.h"
#include "libqtest.h"
-#include "qemu-common.h"
-#include "qemu/sockets.h"
#include "qemu/iov.h"
-#include "libqos/libqos-pc.h"
-#include "libqos/libqos-spapr.h"
-#include "libqos/virtio.h"
-#include "libqos/virtio-pci.h"
#include "qapi/qmp/qdict.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"
+#include "libqos/qgraph.h"
+#include "libqos/virtio-net.h"
#define PCI_SLOT_HP 0x06
#define PCI_SLOT 0x04
@@ -28,65 +21,8 @@
#define QVIRTIO_NET_TIMEOUT_US (30 * 1000 * 1000)
#define VNET_HDR_SIZE sizeof(struct virtio_net_hdr_mrg_rxbuf)
-static void test_end(void)
-{
- qtest_end();
-}
-
#ifndef _WIN32
-static QVirtioPCIDevice *virtio_net_pci_init(QPCIBus *bus, int slot)
-{
- QVirtioPCIDevice *dev;
-
- dev = qvirtio_pci_device_find(bus, VIRTIO_ID_NET);
- g_assert(dev != NULL);
- g_assert_cmphex(dev->vdev.device_type, ==, VIRTIO_ID_NET);
-
- qvirtio_pci_device_enable(dev);
- qvirtio_reset(&dev->vdev);
- qvirtio_set_acknowledge(&dev->vdev);
- qvirtio_set_driver(&dev->vdev);
-
- return dev;
-}
-
-GCC_FMT_ATTR(1, 2)
-static QOSState *pci_test_start(const char *cmd, ...)
-{
- QOSState *qs;
- va_list ap;
- const char *arch = qtest_get_arch();
-
- if (strcmp(arch, "i386") == 0 || strcmp(arch, "x86_64") == 0) {
- va_start(ap, cmd);
- qs = qtest_pc_vboot(cmd, ap);
- va_end(ap);
- } else if (strcmp(arch, "ppc64") == 0) {
- va_start(ap, cmd);
- qs = qtest_spapr_vboot(cmd, ap);
- va_end(ap);
- } else {
- g_printerr("virtio-net tests are only available on x86 or ppc64\n");
- exit(EXIT_FAILURE);
- }
- global_qtest = qs->qts;
- return qs;
-}
-
-static void driver_init(QVirtioDevice *dev)
-{
- uint32_t features;
-
- features = qvirtio_get_features(dev);
- features = features & ~(QVIRTIO_F_BAD_FEATURE |
- (1u << VIRTIO_RING_F_INDIRECT_DESC) |
- (1u << VIRTIO_RING_F_EVENT_IDX));
- qvirtio_set_features(dev, features);
-
- qvirtio_set_driver_ok(dev);
-}
-
static void rx_test(QVirtioDevice *dev,
QGuestAllocator *alloc, QVirtQueue *vq,
int socket)
@@ -196,128 +132,114 @@ static void rx_stop_cont_test(QVirtioDevice *dev,
guest_free(alloc, req_addr);
}
-static void send_recv_test(QVirtioDevice *dev,
- QGuestAllocator *alloc, QVirtQueue *rvq,
- QVirtQueue *tvq, int socket)
+static void send_recv_test(void *obj, void *data, QGuestAllocator *t_alloc)
{
- rx_test(dev, alloc, rvq, socket);
- tx_test(dev, alloc, tvq, socket);
+ QVirtioNet *net_if = obj;
+ QVirtioDevice *dev = net_if->vdev;
+ QVirtQueue *rx = net_if->queues[0];
+ QVirtQueue *tx = net_if->queues[1];
+ int *sv = data;
+
+ rx_test(dev, t_alloc, rx, sv[0]);
+ tx_test(dev, t_alloc, tx, sv[0]);
}
-static void stop_cont_test(QVirtioDevice *dev,
- QGuestAllocator *alloc, QVirtQueue *rvq,
- QVirtQueue *tvq, int socket)
+static void stop_cont_test(void *obj, void *data, QGuestAllocator *t_alloc)
{
- rx_stop_cont_test(dev, alloc, rvq, socket);
+ QVirtioNet *net_if = obj;
+ QVirtioDevice *dev = net_if->vdev;
+ QVirtQueue *rx = net_if->queues[0];
+ int *sv = data;
+
+ rx_stop_cont_test(dev, t_alloc, rx, sv[0]);
}
-static void pci_basic(gconstpointer data)
-{
- QVirtioPCIDevice *dev;
- QOSState *qs;
- QVirtQueuePCI *tx, *rx;
- void (*func) (QVirtioDevice *dev,
- QGuestAllocator *alloc,
- QVirtQueue *rvq,
- QVirtQueue *tvq,
- int socket) = data;
- int sv[2], ret;
+#endif
- ret = socketpair(PF_UNIX, SOCK_STREAM, 0, sv);
- g_assert_cmpint(ret, !=, -1);
+static void hotplug(void *obj, void *data, QGuestAllocator *t_alloc)
+{
+ const char *arch = qtest_get_arch();
- qs = pci_test_start("-netdev socket,fd=%d,id=hs0 -device "
- "virtio-net-pci,netdev=hs0", sv[1]);
- dev = virtio_net_pci_init(qs->pcibus, PCI_SLOT);
+ qtest_qmp_device_add("virtio-net-pci", "net1",
+ "{'addr': %s}", stringify(PCI_SLOT_HP));
- rx = (QVirtQueuePCI *)qvirtqueue_setup(&dev->vdev, qs->alloc, 0);
- tx = (QVirtQueuePCI *)qvirtqueue_setup(&dev->vdev, qs->alloc, 1);
+ if (strcmp(arch, "i386") == 0 || strcmp(arch, "x86_64") == 0) {
+ qpci_unplug_acpi_device_test("net1", PCI_SLOT_HP);
+ }
+}
- driver_init(&dev->vdev);
- func(&dev->vdev, qs->alloc, &rx->vq, &tx->vq, sv[0]);
+static void virtio_net_test_cleanup(void *sockets)
+{
+ int *sv = sockets;
- /* End test */
close(sv[0]);
- qvirtqueue_cleanup(dev->vdev.bus, &tx->vq, qs->alloc);
- qvirtqueue_cleanup(dev->vdev.bus, &rx->vq, qs->alloc);
- qvirtio_pci_device_disable(dev);
- g_free(dev->pdev);
- g_free(dev);
- qtest_shutdown(qs);
+ qos_invalidate_command_line();
+ close(sv[1]);
+ g_free(sv);
+}
+
+static void *virtio_net_test_setup(GString *cmd_line, void *arg)
+{
+ int ret;
+ int *sv = g_new(int, 2);
+
+ ret = socketpair(PF_UNIX, SOCK_STREAM, 0, sv);
+ g_assert_cmpint(ret, !=, -1);
+
+ g_string_append_printf(cmd_line, " -netdev socket,fd=%d,id=hs0 ", sv[1]);
+
+ g_test_queue_destroy(virtio_net_test_cleanup, sv);
+ return sv;
}
-static void large_tx(gconstpointer data)
+static void large_tx(void *obj, void *data, QGuestAllocator *t_alloc)
{
- QVirtioPCIDevice *dev;
- QOSState *qs;
- QVirtQueuePCI *tx, *rx;
- QVirtQueue *vq;
+ QVirtioNet *dev = obj;
+ QVirtQueue *vq = dev->queues[1];
uint64_t req_addr;
uint32_t free_head;
size_t alloc_size = (size_t)data / 64;
int i;
- qs = pci_test_start("-netdev hubport,id=hp0,hubid=0 "
- "-device virtio-net-pci,netdev=hp0");
- dev = virtio_net_pci_init(qs->pcibus, PCI_SLOT);
-
- rx = (QVirtQueuePCI *)qvirtqueue_setup(&dev->vdev, qs->alloc, 0);
- tx = (QVirtQueuePCI *)qvirtqueue_setup(&dev->vdev, qs->alloc, 1);
-
- driver_init(&dev->vdev);
- vq = &tx->vq;
-
/* Bypass the limitation by pointing several descriptors to a single
* smaller area */
- req_addr = guest_alloc(qs->alloc, alloc_size);
+ req_addr = guest_alloc(t_alloc, alloc_size);
free_head = qvirtqueue_add(vq, req_addr, alloc_size, false, true);
for (i = 0; i < 64; i++) {
qvirtqueue_add(vq, req_addr, alloc_size, false, i != 63);
}
- qvirtqueue_kick(&dev->vdev, vq, free_head);
+ qvirtqueue_kick(dev->vdev, vq, free_head);
- qvirtio_wait_used_elem(&dev->vdev, vq, free_head, NULL,
+ qvirtio_wait_used_elem(dev->vdev, vq, free_head, NULL,
QVIRTIO_NET_TIMEOUT_US);
-
- qvirtqueue_cleanup(dev->vdev.bus, &tx->vq, qs->alloc);
- qvirtqueue_cleanup(dev->vdev.bus, &rx->vq, qs->alloc);
- qvirtio_pci_device_disable(dev);
- g_free(dev->pdev);
- g_free(dev);
- qtest_shutdown(qs);
+ guest_free(t_alloc, req_addr);
}
-#endif
-static void hotplug(void)
+static void *virtio_net_test_setup_nosocket(GString *cmd_line, void *arg)
{
- const char *arch = qtest_get_arch();
-
- qtest_start("-device virtio-net-pci");
-
- qtest_qmp_device_add("virtio-net-pci", "net1",
- "{'addr': %s}", stringify(PCI_SLOT_HP));
-
- if (strcmp(arch, "i386") == 0 || strcmp(arch, "x86_64") == 0) {
- qpci_unplug_acpi_device_test("net1", PCI_SLOT_HP);
- }
-
- test_end();
+ g_string_append(cmd_line, " -netdev hubport,hubid=0,id=hs0 ");
+ return arg;
}
-int main(int argc, char **argv)
+static void register_virtio_net_test(void)
{
- g_test_init(&argc, &argv, NULL);
+ QOSGraphTestOptions opts = {
+ .before = virtio_net_test_setup,
+ };
+
+ qos_add_test("hotplug", "virtio-pci", hotplug, &opts);
#ifndef _WIN32
- qtest_add_data_func("/virtio/net/pci/basic", send_recv_test, pci_basic);
- qtest_add_data_func("/virtio/net/pci/rx_stop_cont",
- stop_cont_test, pci_basic);
- qtest_add_data_func("/virtio/net/pci/large_tx_uint_max",
- (gconstpointer)UINT_MAX, large_tx);
- qtest_add_data_func("/virtio/net/pci/large_tx_net_bufsize",
- (gconstpointer)NET_BUFSIZE, large_tx);
+ qos_add_test("basic", "virtio-net", send_recv_test, &opts);
+ qos_add_test("rx_stop_cont", "virtio-net", stop_cont_test, &opts);
#endif
- qtest_add_func("/virtio/net/pci/hotplug", hotplug);
- return g_test_run();
+ /* These tests do not need a loopback backend. */
+ opts.before = virtio_net_test_setup_nosocket;
+ opts.arg = (gpointer)UINT_MAX;
+ qos_add_test("large_tx/uint_max", "virtio-net", large_tx, &opts);
+ opts.arg = (gpointer)NET_BUFSIZE;
+ qos_add_test("large_tx/net_bufsize", "virtio-net", large_tx, &opts);
}
+
+libqos_init(register_virtio_net_test);
diff --git a/tests/virtio-rng-test.c b/tests/virtio-rng-test.c
index 657d9a4105..5309c7c8ab 100644
--- a/tests/virtio-rng-test.c
+++ b/tests/virtio-rng-test.c
@@ -9,16 +9,12 @@
#include "qemu/osdep.h"
#include "libqtest.h"
-#include "libqos/pci.h"
+#include "libqos/qgraph.h"
+#include "libqos/virtio-rng.h"
#define PCI_SLOT_HP 0x06
-/* Tests only initialization so far. TODO: Replace with functional tests */
-static void pci_nop(void)
-{
-}
-
-static void hotplug(void)
+static void rng_hotplug(void *obj, void *data, QGuestAllocator *alloc)
{
const char *arch = qtest_get_arch();
@@ -30,18 +26,9 @@ static void hotplug(void)
}
}
-int main(int argc, char **argv)
+static void register_virtio_rng_test(void)
{
- int ret;
-
- g_test_init(&argc, &argv, NULL);
- qtest_add_func("/virtio/rng/pci/nop", pci_nop);
- qtest_add_func("/virtio/rng/pci/hotplug", hotplug);
-
- qtest_start("-device virtio-rng-pci");
- ret = g_test_run();
-
- qtest_end();
-
- return ret;
+ qos_add_test("hotplug", "virtio-rng-pci", rng_hotplug, NULL);
}
+
+libqos_init(register_virtio_rng_test);
diff --git a/tests/virtio-scsi-test.c b/tests/virtio-scsi-test.c
index 0d4f25d369..162b31c88d 100644
--- a/tests/virtio-scsi-test.c
+++ b/tests/virtio-scsi-test.c
@@ -18,6 +18,8 @@
#include "standard-headers/linux/virtio_ids.h"
#include "standard-headers/linux/virtio_pci.h"
#include "standard-headers/linux/virtio_scsi.h"
+#include "libqos/virtio-scsi.h"
+#include "libqos/qgraph.h"
#define PCI_SLOT 0x02
#define PCI_FN 0x00
@@ -27,55 +29,28 @@
typedef struct {
QVirtioDevice *dev;
- QOSState *qs;
int num_queues;
QVirtQueue *vq[MAX_NUM_QUEUES + 2];
-} QVirtIOSCSI;
+} QVirtioSCSIQueues;
-static QOSState *qvirtio_scsi_start(const char *extra_opts)
-{
- QOSState *qs;
- const char *arch = qtest_get_arch();
- const char *cmd = "-drive id=drv0,if=none,file=null-co://,format=raw "
- "-device virtio-scsi-pci,id=vs0 "
- "-device scsi-hd,bus=vs0.0,drive=drv0 %s";
-
- if (strcmp(arch, "i386") == 0 || strcmp(arch, "x86_64") == 0) {
- qs = qtest_pc_boot(cmd, extra_opts ? : "");
- } else if (strcmp(arch, "ppc64") == 0) {
- qs = qtest_spapr_boot(cmd, extra_opts ? : "");
- } else {
- g_printerr("virtio-scsi tests are only available on x86 or ppc64\n");
- exit(EXIT_FAILURE);
- }
- global_qtest = qs->qts;
- return qs;
-}
-
-static void qvirtio_scsi_stop(QOSState *qs)
-{
- qtest_shutdown(qs);
-}
+static QGuestAllocator *alloc;
-static void qvirtio_scsi_pci_free(QVirtIOSCSI *vs)
+static void qvirtio_scsi_pci_free(QVirtioSCSIQueues *vs)
{
int i;
for (i = 0; i < vs->num_queues + 2; i++) {
- qvirtqueue_cleanup(vs->dev->bus, vs->vq[i], vs->qs->alloc);
+ qvirtqueue_cleanup(vs->dev->bus, vs->vq[i], alloc);
}
- qvirtio_pci_device_disable(container_of(vs->dev, QVirtioPCIDevice, vdev));
- qvirtio_pci_device_free((QVirtioPCIDevice *)vs->dev);
- qvirtio_scsi_stop(vs->qs);
g_free(vs);
}
-static uint64_t qvirtio_scsi_alloc(QVirtIOSCSI *vs, size_t alloc_size,
+static uint64_t qvirtio_scsi_alloc(QVirtioSCSIQueues *vs, size_t alloc_size,
const void *data)
{
uint64_t addr;
- addr = guest_alloc(vs->qs->alloc, alloc_size);
+ addr = guest_alloc(alloc, alloc_size);
if (data) {
memwrite(addr, data, alloc_size);
}
@@ -83,7 +58,8 @@ static uint64_t qvirtio_scsi_alloc(QVirtIOSCSI *vs, size_t alloc_size,
return addr;
}
-static uint8_t virtio_scsi_do_command(QVirtIOSCSI *vs, const uint8_t *cdb,
+static uint8_t virtio_scsi_do_command(QVirtioSCSIQueues *vs,
+ const uint8_t *cdb,
const uint8_t *data_in,
size_t data_in_len,
uint8_t *data_out, size_t data_out_len,
@@ -133,42 +109,28 @@ static uint8_t virtio_scsi_do_command(QVirtIOSCSI *vs, const uint8_t *cdb,
memread(resp_addr, resp_out, sizeof(*resp_out));
}
- guest_free(vs->qs->alloc, req_addr);
- guest_free(vs->qs->alloc, resp_addr);
- guest_free(vs->qs->alloc, data_in_addr);
- guest_free(vs->qs->alloc, data_out_addr);
+ guest_free(alloc, req_addr);
+ guest_free(alloc, resp_addr);
+ guest_free(alloc, data_in_addr);
+ guest_free(alloc, data_out_addr);
return response;
}
-static QVirtIOSCSI *qvirtio_scsi_pci_init(int slot)
+static QVirtioSCSIQueues *qvirtio_scsi_init(QVirtioDevice *dev)
{
+ QVirtioSCSIQueues *vs;
const uint8_t test_unit_ready_cdb[VIRTIO_SCSI_CDB_SIZE] = {};
- QVirtIOSCSI *vs;
- QVirtioPCIDevice *dev;
struct virtio_scsi_cmd_resp resp;
int i;
- vs = g_new0(QVirtIOSCSI, 1);
-
- vs->qs = qvirtio_scsi_start("-drive file=blkdebug::null-co://,"
- "if=none,id=dr1,format=raw,file.align=4k "
- "-device scsi-hd,drive=dr1,lun=0,scsi-id=1");
- dev = qvirtio_pci_device_find(vs->qs->pcibus, VIRTIO_ID_SCSI);
- vs->dev = (QVirtioDevice *)dev;
- g_assert(dev != NULL);
- g_assert_cmphex(vs->dev->device_type, ==, VIRTIO_ID_SCSI);
-
- qvirtio_pci_device_enable(dev);
- qvirtio_reset(vs->dev);
- qvirtio_set_acknowledge(vs->dev);
- qvirtio_set_driver(vs->dev);
-
- vs->num_queues = qvirtio_config_readl(vs->dev, 0);
+ vs = g_new0(QVirtioSCSIQueues, 1);
+ vs->dev = dev;
+ vs->num_queues = qvirtio_config_readl(dev, 0);
g_assert_cmpint(vs->num_queues, <, MAX_NUM_QUEUES);
for (i = 0; i < vs->num_queues + 2; i++) {
- vs->vq[i] = qvirtqueue_setup(vs->dev, vs->qs->alloc, i);
+ vs->vq[i] = qvirtqueue_setup(dev, alloc, i);
}
/* Clear the POWER ON OCCURRED unit attention */
@@ -184,30 +146,18 @@ static QVirtIOSCSI *qvirtio_scsi_pci_init(int slot)
return vs;
}
-/* Tests only initialization so far. TODO: Replace with functional tests */
-static void pci_nop(void)
-{
- QOSState *qs;
-
- qs = qvirtio_scsi_start(NULL);
- qvirtio_scsi_stop(qs);
-}
-
-static void hotplug(void)
+static void hotplug(void *obj, void *data, QGuestAllocator *alloc)
{
- QOSState *qs;
-
- qs = qvirtio_scsi_start(
- "-drive id=drv1,if=none,file=null-co://,format=raw");
qtest_qmp_device_add("scsi-hd", "scsihd", "{'drive': 'drv1'}");
qtest_qmp_device_del("scsihd");
- qvirtio_scsi_stop(qs);
}
/* Test WRITE SAME with the lba not aligned */
-static void test_unaligned_write_same(void)
+static void test_unaligned_write_same(void *obj, void *data,
+ QGuestAllocator *t_alloc)
{
- QVirtIOSCSI *vs;
+ QVirtioSCSI *scsi = obj;
+ QVirtioSCSIQueues *vs;
uint8_t buf1[512] = { 0 };
uint8_t buf2[512] = { 1 };
const uint8_t write_same_cdb_1[VIRTIO_SCSI_CDB_SIZE] = {
@@ -220,27 +170,50 @@ static void test_unaligned_write_same(void)
0x41, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x33, 0x00, 0x00
};
- vs = qvirtio_scsi_pci_init(PCI_SLOT);
+ alloc = t_alloc;
+ vs = qvirtio_scsi_init(scsi->vdev);
g_assert_cmphex(0, ==,
- virtio_scsi_do_command(vs, write_same_cdb_1, NULL, 0, buf1, 512, NULL));
+ virtio_scsi_do_command(vs, write_same_cdb_1, NULL, 0, buf1, 512,
+ NULL));
g_assert_cmphex(0, ==,
- virtio_scsi_do_command(vs, write_same_cdb_2, NULL, 0, buf2, 512, NULL));
+ virtio_scsi_do_command(vs, write_same_cdb_2, NULL, 0, buf2, 512,
+ NULL));
g_assert_cmphex(0, ==,
- virtio_scsi_do_command(vs, write_same_cdb_ndob, NULL, 0, NULL, 0, NULL));
+ virtio_scsi_do_command(vs, write_same_cdb_ndob, NULL, 0, NULL, 0,
+ NULL));
qvirtio_scsi_pci_free(vs);
}
-int main(int argc, char **argv)
+static void *virtio_scsi_hotplug_setup(GString *cmd_line, void *arg)
{
- 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);
+ g_string_append(cmd_line,
+ " -drive id=drv1,if=none,file=null-co://,format=raw");
+ return arg;
+}
- return g_test_run();
+static void *virtio_scsi_setup(GString *cmd_line, void *arg)
+{
+ g_string_append(cmd_line,
+ " -drive file=blkdebug::null-co://,"
+ "if=none,id=dr1,format=raw,file.align=4k "
+ "-device scsi-hd,drive=dr1,lun=0,scsi-id=1");
+ return arg;
}
+
+static void register_virtio_scsi_test(void)
+{
+ QOSGraphTestOptions opts = { };
+
+ opts.before = virtio_scsi_hotplug_setup;
+ qos_add_test("hotplug", "virtio-scsi", hotplug, &opts);
+
+ opts.before = virtio_scsi_setup;
+ qos_add_test("unaligned-write-same", "virtio-scsi",
+ test_unaligned_write_same, &opts);
+}
+
+libqos_init(register_virtio_scsi_test);
diff --git a/tests/virtio-serial-test.c b/tests/virtio-serial-test.c
index 8da9980a24..85f35e09b7 100644
--- a/tests/virtio-serial-test.c
+++ b/tests/virtio-serial-test.c
@@ -9,33 +9,30 @@
#include "qemu/osdep.h"
#include "libqtest.h"
-#include "libqos/virtio.h"
+#include "libqos/virtio-serial.h"
/* Tests only initialization so far. TODO: Replace with functional tests */
-static void virtio_serial_nop(void)
+static void virtio_serial_nop(void *obj, void *data, QGuestAllocator *alloc)
{
+ /* no operation */
}
-static void hotplug(void)
+static void serial_hotplug(void *obj, void *data, QGuestAllocator *alloc)
{
qtest_qmp_device_add("virtserialport", "hp-port", "{}");
-
qtest_qmp_device_del("hp-port");
}
-int main(int argc, char **argv)
+static void register_virtio_serial_test(void)
{
- int ret;
-
- g_test_init(&argc, &argv, NULL);
- qtest_add_func("/virtio/serial/nop", virtio_serial_nop);
- qtest_add_func("/virtio/serial/hotplug", hotplug);
+ QOSGraphTestOptions opts = { };
- global_qtest = qtest_initf("-device virtio-serial-%s",
- qvirtio_get_dev_type());
- ret = g_test_run();
+ opts.edge.before_cmd_line = "-device virtconsole,bus=vser0.0";
+ qos_add_test("console-nop", "virtio-serial", virtio_serial_nop, &opts);
- qtest_end();
+ opts.edge.before_cmd_line = "-device virtserialport,bus=vser0.0";
+ qos_add_test("serialport-nop", "virtio-serial", virtio_serial_nop, &opts);
- return ret;
+ qos_add_test("hotplug", "virtio-serial", serial_hotplug, NULL);
}
+libqos_init(register_virtio_serial_test);
diff --git a/tests/virtio-test.c b/tests/virtio-test.c
new file mode 100644
index 0000000000..804e5371dc
--- /dev/null
+++ b/tests/virtio-test.c
@@ -0,0 +1,25 @@
+/*
+ * QTest testcase for virtio
+ *
+ * Copyright (c) 2018 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 "libqtest.h"
+#include "libqos/qgraph.h"
+#include "libqos/pci.h"
+
+/* Tests only initialization so far. TODO: Replace with functional tests */
+static void nop(void *obj, void *data, QGuestAllocator *alloc)
+{
+}
+
+static void register_virtio_test(void)
+{
+ qos_add_test("nop", "virtio", nop, NULL);
+}
+
+libqos_init(register_virtio_test);
diff --git a/tests/vmxnet3-test.c b/tests/vmxnet3-test.c
index 159c0ad728..35cdea939b 100644
--- a/tests/vmxnet3-test.c
+++ b/tests/vmxnet3-test.c
@@ -9,23 +9,49 @@
#include "qemu/osdep.h"
#include "libqtest.h"
+#include "libqos/qgraph.h"
+#include "libqos/pci.h"
-/* Tests only initialization so far. TODO: Replace with functional tests */
-static void nop(void)
+typedef struct QVmxnet3 QVmxnet3;
+
+struct QVmxnet3 {
+ QOSGraphObject obj;
+ QPCIDevice dev;
+};
+
+static void *vmxnet3_get_driver(void *obj, const char *interface)
{
+ QVmxnet3 *vmxnet3 = obj;
+
+ if (!g_strcmp0(interface, "pci-device")) {
+ return &vmxnet3->dev;
+ }
+
+ fprintf(stderr, "%s not present in vmxnet3\n", interface);
+ g_assert_not_reached();
}
-int main(int argc, char **argv)
+static void *vmxnet3_create(void *pci_bus, QGuestAllocator *alloc, void *addr)
{
- int ret;
+ QVmxnet3 *vmxnet3 = g_new0(QVmxnet3, 1);
+ QPCIBus *bus = pci_bus;
- g_test_init(&argc, &argv, NULL);
- qtest_add_func("/vmxnet3/nop", nop);
+ qpci_device_init(&vmxnet3->dev, bus, addr);
+ vmxnet3->obj.get_driver = vmxnet3_get_driver;
- qtest_start("-device vmxnet3");
- ret = g_test_run();
+ return &vmxnet3->obj;
+}
- qtest_end();
+static void vmxnet3_register_nodes(void)
+{
+ QOSGraphEdgeOptions opts = {
+ .extra_device_opts = "addr=04.0",
+ };
+ add_qpci_address(&opts, &(QPCIAddress) { .devfn = QPCI_DEVFN(4, 0) });
- return ret;
+ qos_node_create_driver("vmxnet3", vmxnet3_create);
+ qos_node_consumes("vmxnet3", "pci-bus", &opts);
+ qos_node_produces("vmxnet3", "pci-device");
}
+
+libqos_init(vmxnet3_register_nodes);