aboutsummaryrefslogtreecommitdiff
path: root/tests
diff options
context:
space:
mode:
Diffstat (limited to 'tests')
-rw-r--r--tests/avocado/igb.py38
-rw-r--r--tests/data/acpi/pc/DSDTbin6360 -> 6488 bytes
-rw-r--r--tests/data/acpi/pc/DSDT.acpierstbin6283 -> 6411 bytes
-rw-r--r--tests/data/acpi/pc/DSDT.acpihmatbin7685 -> 7813 bytes
-rw-r--r--tests/data/acpi/pc/DSDT.bridgebin12487 -> 12615 bytes
-rw-r--r--tests/data/acpi/pc/DSDT.cphpbin6824 -> 6952 bytes
-rw-r--r--tests/data/acpi/pc/DSDT.dimmpxmbin8014 -> 8142 bytes
-rw-r--r--tests/data/acpi/pc/DSDT.hpbridgebin6289 -> 6451 bytes
-rw-r--r--tests/data/acpi/pc/DSDT.hpbrrootbin3081 -> 3343 bytes
-rw-r--r--tests/data/acpi/pc/DSDT.ipmikcsbin6432 -> 6560 bytes
-rw-r--r--tests/data/acpi/pc/DSDT.memhpbin7719 -> 7847 bytes
-rw-r--r--tests/data/acpi/pc/DSDT.nohpetbin6218 -> 6346 bytes
-rw-r--r--tests/data/acpi/pc/DSDT.numamembin6366 -> 6494 bytes
-rw-r--r--tests/data/acpi/pc/DSDT.roothpbin9745 -> 9873 bytes
-rw-r--r--tests/data/acpi/q35/DSDTbin8252 -> 8361 bytes
-rw-r--r--tests/data/acpi/q35/DSDT.acpierstbin8269 -> 8378 bytes
-rw-r--r--tests/data/acpi/q35/DSDT.acpihmatbin9577 -> 9686 bytes
-rw-r--r--tests/data/acpi/q35/DSDT.acpihmat-noinitiatorbin8531 -> 8640 bytes
-rw-r--r--tests/data/acpi/q35/DSDT.applesmcbin8298 -> 8407 bytes
-rw-r--r--tests/data/acpi/q35/DSDT.bridgebin11481 -> 11590 bytes
-rw-r--r--tests/data/acpi/q35/DSDT.core-count2bin32392 -> 32501 bytes
-rw-r--r--tests/data/acpi/q35/DSDT.cphpbin8716 -> 8825 bytes
-rw-r--r--tests/data/acpi/q35/DSDT.cxlbin9564 -> 9673 bytes
-rw-r--r--tests/data/acpi/q35/DSDT.dimmpxmbin9906 -> 10015 bytes
-rw-r--r--tests/data/acpi/q35/DSDT.ipmibtbin8327 -> 8436 bytes
-rw-r--r--tests/data/acpi/q35/DSDT.ipmismbusbin8340 -> 8449 bytes
-rw-r--r--tests/data/acpi/q35/DSDT.ivrsbin8269 -> 8378 bytes
-rw-r--r--tests/data/acpi/q35/DSDT.memhpbin9611 -> 9720 bytes
-rw-r--r--tests/data/acpi/q35/DSDT.mmio64bin9382 -> 9491 bytes
-rw-r--r--tests/data/acpi/q35/DSDT.multi-bridgebin12337 -> 12770 bytes
-rw-r--r--tests/data/acpi/q35/DSDT.noacpihpbin0 -> 8248 bytes
-rw-r--r--tests/data/acpi/q35/DSDT.nohpetbin8110 -> 8219 bytes
-rw-r--r--tests/data/acpi/q35/DSDT.numamembin8258 -> 8367 bytes
-rw-r--r--tests/data/acpi/q35/DSDT.pvpanic-isabin8353 -> 8462 bytes
-rw-r--r--tests/data/acpi/q35/DSDT.tis.tpm12bin8858 -> 8967 bytes
-rw-r--r--tests/data/acpi/q35/DSDT.tis.tpm2bin8884 -> 8993 bytes
-rw-r--r--tests/data/acpi/q35/DSDT.viotbin9361 -> 9470 bytes
-rw-r--r--tests/data/acpi/q35/DSDT.xapicbin35615 -> 35724 bytes
-rw-r--r--tests/qtest/bios-tables-test.c125
-rw-r--r--tests/qtest/e1000e-test.c25
-rw-r--r--tests/qtest/fuzz/generic_fuzz_configs.h5
-rw-r--r--tests/qtest/igb-test.c256
-rw-r--r--tests/qtest/libqos/e1000e.c12
-rw-r--r--tests/qtest/libqos/e1000e.h14
-rw-r--r--tests/qtest/libqos/igb.c185
-rw-r--r--tests/qtest/libqos/meson.build1
-rw-r--r--tests/qtest/meson.build1
-rw-r--r--tests/tcg/hexagon/Makefile.target13
-rw-r--r--tests/tcg/hexagon/fpstuff.c31
-rw-r--r--tests/tcg/hexagon/preg_alias.c10
-rw-r--r--tests/tcg/hexagon/scatter_gather.c513
51 files changed, 883 insertions, 346 deletions
diff --git a/tests/avocado/igb.py b/tests/avocado/igb.py
new file mode 100644
index 0000000..abf5dfa
--- /dev/null
+++ b/tests/avocado/igb.py
@@ -0,0 +1,38 @@
+# SPDX-License-Identifier: GPL-2.0-or-later
+# ethtool tests for igb registers, interrupts, etc
+
+from avocado_qemu import LinuxTest
+
+class IGB(LinuxTest):
+ """
+ :avocado: tags=accel:kvm
+ :avocado: tags=arch:x86_64
+ :avocado: tags=distro:fedora
+ :avocado: tags=distro_version:31
+ :avocado: tags=machine:q35
+ """
+
+ timeout = 180
+
+ def test(self):
+ self.require_accelerator('kvm')
+ kernel_url = self.distro.pxeboot_url + 'vmlinuz'
+ kernel_hash = '5b6f6876e1b5bda314f93893271da0d5777b1f3c'
+ kernel_path = self.fetch_asset(kernel_url, asset_hash=kernel_hash)
+ initrd_url = self.distro.pxeboot_url + 'initrd.img'
+ initrd_hash = 'dd0340a1b39bd28f88532babd4581c67649ec5b1'
+ initrd_path = self.fetch_asset(initrd_url, asset_hash=initrd_hash)
+
+ # Ideally we want to test MSI as well, but it is blocked by a bug
+ # fixed with:
+ # https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=28e96556baca7056d11d9fb3cdd0aba4483e00d8
+ kernel_params = self.distro.default_kernel_params + ' pci=nomsi'
+
+ self.vm.add_args('-kernel', kernel_path,
+ '-initrd', initrd_path,
+ '-append', kernel_params,
+ '-accel', 'kvm',
+ '-device', 'igb')
+ self.launch_and_wait()
+ self.ssh_command('dnf -y install ethtool')
+ self.ssh_command('ethtool -t eth1 offline')
diff --git a/tests/data/acpi/pc/DSDT b/tests/data/acpi/pc/DSDT
index 0b475fb..32d255c 100644
--- a/tests/data/acpi/pc/DSDT
+++ b/tests/data/acpi/pc/DSDT
Binary files differ
diff --git a/tests/data/acpi/pc/DSDT.acpierst b/tests/data/acpi/pc/DSDT.acpierst
index 17ef7ca..33e872b 100644
--- a/tests/data/acpi/pc/DSDT.acpierst
+++ b/tests/data/acpi/pc/DSDT.acpierst
Binary files differ
diff --git a/tests/data/acpi/pc/DSDT.acpihmat b/tests/data/acpi/pc/DSDT.acpihmat
index 675b674..cd84abc 100644
--- a/tests/data/acpi/pc/DSDT.acpihmat
+++ b/tests/data/acpi/pc/DSDT.acpihmat
Binary files differ
diff --git a/tests/data/acpi/pc/DSDT.bridge b/tests/data/acpi/pc/DSDT.bridge
index c1ce061..69a73ea 100644
--- a/tests/data/acpi/pc/DSDT.bridge
+++ b/tests/data/acpi/pc/DSDT.bridge
Binary files differ
diff --git a/tests/data/acpi/pc/DSDT.cphp b/tests/data/acpi/pc/DSDT.cphp
index 754ab85..2037905 100644
--- a/tests/data/acpi/pc/DSDT.cphp
+++ b/tests/data/acpi/pc/DSDT.cphp
Binary files differ
diff --git a/tests/data/acpi/pc/DSDT.dimmpxm b/tests/data/acpi/pc/DSDT.dimmpxm
index 1705033..435496e 100644
--- a/tests/data/acpi/pc/DSDT.dimmpxm
+++ b/tests/data/acpi/pc/DSDT.dimmpxm
Binary files differ
diff --git a/tests/data/acpi/pc/DSDT.hpbridge b/tests/data/acpi/pc/DSDT.hpbridge
index 834c270..b6eafab 100644
--- a/tests/data/acpi/pc/DSDT.hpbridge
+++ b/tests/data/acpi/pc/DSDT.hpbridge
Binary files differ
diff --git a/tests/data/acpi/pc/DSDT.hpbrroot b/tests/data/acpi/pc/DSDT.hpbrroot
index a71ed4f..a4073f3 100644
--- a/tests/data/acpi/pc/DSDT.hpbrroot
+++ b/tests/data/acpi/pc/DSDT.hpbrroot
Binary files differ
diff --git a/tests/data/acpi/pc/DSDT.ipmikcs b/tests/data/acpi/pc/DSDT.ipmikcs
index dd71356..06aa7bfd 100644
--- a/tests/data/acpi/pc/DSDT.ipmikcs
+++ b/tests/data/acpi/pc/DSDT.ipmikcs
Binary files differ
diff --git a/tests/data/acpi/pc/DSDT.memhp b/tests/data/acpi/pc/DSDT.memhp
index 2f895e9..10a0e44 100644
--- a/tests/data/acpi/pc/DSDT.memhp
+++ b/tests/data/acpi/pc/DSDT.memhp
Binary files differ
diff --git a/tests/data/acpi/pc/DSDT.nohpet b/tests/data/acpi/pc/DSDT.nohpet
index c012b63..6905312 100644
--- a/tests/data/acpi/pc/DSDT.nohpet
+++ b/tests/data/acpi/pc/DSDT.nohpet
Binary files differ
diff --git a/tests/data/acpi/pc/DSDT.numamem b/tests/data/acpi/pc/DSDT.numamem
index f2ef4b9..59e3133 100644
--- a/tests/data/acpi/pc/DSDT.numamem
+++ b/tests/data/acpi/pc/DSDT.numamem
Binary files differ
diff --git a/tests/data/acpi/pc/DSDT.roothp b/tests/data/acpi/pc/DSDT.roothp
index 657c826..448d596 100644
--- a/tests/data/acpi/pc/DSDT.roothp
+++ b/tests/data/acpi/pc/DSDT.roothp
Binary files differ
diff --git a/tests/data/acpi/q35/DSDT b/tests/data/acpi/q35/DSDT
index d68c472..720e8cb 100644
--- a/tests/data/acpi/q35/DSDT
+++ b/tests/data/acpi/q35/DSDT
Binary files differ
diff --git a/tests/data/acpi/q35/DSDT.acpierst b/tests/data/acpi/q35/DSDT.acpierst
index de7ae27..f26b1f2 100644
--- a/tests/data/acpi/q35/DSDT.acpierst
+++ b/tests/data/acpi/q35/DSDT.acpierst
Binary files differ
diff --git a/tests/data/acpi/q35/DSDT.acpihmat b/tests/data/acpi/q35/DSDT.acpihmat
index 48e2862..86771f1 100644
--- a/tests/data/acpi/q35/DSDT.acpihmat
+++ b/tests/data/acpi/q35/DSDT.acpihmat
Binary files differ
diff --git a/tests/data/acpi/q35/DSDT.acpihmat-noinitiator b/tests/data/acpi/q35/DSDT.acpihmat-noinitiator
index 30a4aa2..a894a2d 100644
--- a/tests/data/acpi/q35/DSDT.acpihmat-noinitiator
+++ b/tests/data/acpi/q35/DSDT.acpihmat-noinitiator
Binary files differ
diff --git a/tests/data/acpi/q35/DSDT.applesmc b/tests/data/acpi/q35/DSDT.applesmc
index 84e2b5c..276ae1d 100644
--- a/tests/data/acpi/q35/DSDT.applesmc
+++ b/tests/data/acpi/q35/DSDT.applesmc
Binary files differ
diff --git a/tests/data/acpi/q35/DSDT.bridge b/tests/data/acpi/q35/DSDT.bridge
index e411d40..9f8a208 100644
--- a/tests/data/acpi/q35/DSDT.bridge
+++ b/tests/data/acpi/q35/DSDT.bridge
Binary files differ
diff --git a/tests/data/acpi/q35/DSDT.core-count2 b/tests/data/acpi/q35/DSDT.core-count2
index 0603db8..2ec11fe 100644
--- a/tests/data/acpi/q35/DSDT.core-count2
+++ b/tests/data/acpi/q35/DSDT.core-count2
Binary files differ
diff --git a/tests/data/acpi/q35/DSDT.cphp b/tests/data/acpi/q35/DSDT.cphp
index beeb83c..612c85b 100644
--- a/tests/data/acpi/q35/DSDT.cphp
+++ b/tests/data/acpi/q35/DSDT.cphp
Binary files differ
diff --git a/tests/data/acpi/q35/DSDT.cxl b/tests/data/acpi/q35/DSDT.cxl
index 4586b9a..f049f41 100644
--- a/tests/data/acpi/q35/DSDT.cxl
+++ b/tests/data/acpi/q35/DSDT.cxl
Binary files differ
diff --git a/tests/data/acpi/q35/DSDT.dimmpxm b/tests/data/acpi/q35/DSDT.dimmpxm
index 99a93e1..23dabea 100644
--- a/tests/data/acpi/q35/DSDT.dimmpxm
+++ b/tests/data/acpi/q35/DSDT.dimmpxm
Binary files differ
diff --git a/tests/data/acpi/q35/DSDT.ipmibt b/tests/data/acpi/q35/DSDT.ipmibt
index 7f7601d..541bb70 100644
--- a/tests/data/acpi/q35/DSDT.ipmibt
+++ b/tests/data/acpi/q35/DSDT.ipmibt
Binary files differ
diff --git a/tests/data/acpi/q35/DSDT.ipmismbus b/tests/data/acpi/q35/DSDT.ipmismbus
index 6c5d1af..e2d57a3 100644
--- a/tests/data/acpi/q35/DSDT.ipmismbus
+++ b/tests/data/acpi/q35/DSDT.ipmismbus
Binary files differ
diff --git a/tests/data/acpi/q35/DSDT.ivrs b/tests/data/acpi/q35/DSDT.ivrs
index de7ae27..f26b1f2 100644
--- a/tests/data/acpi/q35/DSDT.ivrs
+++ b/tests/data/acpi/q35/DSDT.ivrs
Binary files differ
diff --git a/tests/data/acpi/q35/DSDT.memhp b/tests/data/acpi/q35/DSDT.memhp
index 79bce5c..809d7e2 100644
--- a/tests/data/acpi/q35/DSDT.memhp
+++ b/tests/data/acpi/q35/DSDT.memhp
Binary files differ
diff --git a/tests/data/acpi/q35/DSDT.mmio64 b/tests/data/acpi/q35/DSDT.mmio64
index c249929..ab3fe3c 100644
--- a/tests/data/acpi/q35/DSDT.mmio64
+++ b/tests/data/acpi/q35/DSDT.mmio64
Binary files differ
diff --git a/tests/data/acpi/q35/DSDT.multi-bridge b/tests/data/acpi/q35/DSDT.multi-bridge
index 66b39be..9ae8ee0 100644
--- a/tests/data/acpi/q35/DSDT.multi-bridge
+++ b/tests/data/acpi/q35/DSDT.multi-bridge
Binary files differ
diff --git a/tests/data/acpi/q35/DSDT.noacpihp b/tests/data/acpi/q35/DSDT.noacpihp
new file mode 100644
index 0000000..6ab1f0e
--- /dev/null
+++ b/tests/data/acpi/q35/DSDT.noacpihp
Binary files differ
diff --git a/tests/data/acpi/q35/DSDT.nohpet b/tests/data/acpi/q35/DSDT.nohpet
index 9ff9983..becb5f7 100644
--- a/tests/data/acpi/q35/DSDT.nohpet
+++ b/tests/data/acpi/q35/DSDT.nohpet
Binary files differ
diff --git a/tests/data/acpi/q35/DSDT.numamem b/tests/data/acpi/q35/DSDT.numamem
index 1e7c45e..0cdec0b 100644
--- a/tests/data/acpi/q35/DSDT.numamem
+++ b/tests/data/acpi/q35/DSDT.numamem
Binary files differ
diff --git a/tests/data/acpi/q35/DSDT.pvpanic-isa b/tests/data/acpi/q35/DSDT.pvpanic-isa
index ed47451..6a9904e 100644
--- a/tests/data/acpi/q35/DSDT.pvpanic-isa
+++ b/tests/data/acpi/q35/DSDT.pvpanic-isa
Binary files differ
diff --git a/tests/data/acpi/q35/DSDT.tis.tpm12 b/tests/data/acpi/q35/DSDT.tis.tpm12
index efc2efc..628bf62 100644
--- a/tests/data/acpi/q35/DSDT.tis.tpm12
+++ b/tests/data/acpi/q35/DSDT.tis.tpm12
Binary files differ
diff --git a/tests/data/acpi/q35/DSDT.tis.tpm2 b/tests/data/acpi/q35/DSDT.tis.tpm2
index 6753397..35c6b08 100644
--- a/tests/data/acpi/q35/DSDT.tis.tpm2
+++ b/tests/data/acpi/q35/DSDT.tis.tpm2
Binary files differ
diff --git a/tests/data/acpi/q35/DSDT.viot b/tests/data/acpi/q35/DSDT.viot
index eeb40b3..3ad4d26 100644
--- a/tests/data/acpi/q35/DSDT.viot
+++ b/tests/data/acpi/q35/DSDT.viot
Binary files differ
diff --git a/tests/data/acpi/q35/DSDT.xapic b/tests/data/acpi/q35/DSDT.xapic
index 3aa86f0..d4a34e2 100644
--- a/tests/data/acpi/q35/DSDT.xapic
+++ b/tests/data/acpi/q35/DSDT.xapic
Binary files differ
diff --git a/tests/qtest/bios-tables-test.c b/tests/qtest/bios-tables-test.c
index d29a4e4..76d5100 100644
--- a/tests/qtest/bios-tables-test.c
+++ b/tests/qtest/bios-tables-test.c
@@ -949,9 +949,14 @@ static void test_acpi_piix4_no_acpi_pci_hotplug(void)
data.required_struct_types_len = ARRAY_SIZE(base_required_struct_types);
test_acpi_one("-global PIIX4_PM.acpi-root-pci-hotplug=off "
"-global PIIX4_PM.acpi-pci-hotplug-with-bridge-support=off "
- "-device pci-bridge,chassis_nr=1 "
- "-device pci-testdev,bus=pci.0 "
- "-device pci-testdev,bus=pci.1", &data);
+ "-device pci-bridge,chassis_nr=1,addr=4.0 "
+ "-device pci-testdev,bus=pci.0,addr=5.0 "
+ "-device pci-testdev,bus=pci.0,addr=6.0,acpi-index=101 "
+ "-device pci-testdev,bus=pci.1,addr=1.0 "
+ "-device pci-testdev,bus=pci.1,addr=2.0,acpi-index=201 "
+ "-device pci-bridge,id=nhpbr,chassis_nr=2,shpc=off,addr=7.0 "
+ "-device pci-testdev,bus=nhpbr,addr=1.0,acpi-index=301 "
+ , &data);
free_test_data(&data);
}
@@ -1002,18 +1007,42 @@ static void test_acpi_q35_tcg_bridge(void)
free_test_data(&data);
}
+static void test_acpi_q35_tcg_no_acpi_hotplug(void)
+{
+ test_data data;
+
+ memset(&data, 0, sizeof(data));
+ data.machine = MACHINE_Q35;
+ data.variant = ".noacpihp";
+ data.required_struct_types = base_required_struct_types;
+ data.required_struct_types_len = ARRAY_SIZE(base_required_struct_types);
+ test_acpi_one("-global ICH9-LPC.acpi-pci-hotplug-with-bridge-support=off"
+ " -device pci-testdev,bus=pcie.0,acpi-index=101,addr=3.0"
+ " -device pci-bridge,chassis_nr=1,id=shpcbr,addr=4.0"
+ " -device pci-testdev,bus=shpcbr,addr=1.0,acpi-index=201"
+ " -device pci-bridge,chassis_nr=2,shpc=off,id=noshpcbr,addr=5.0"
+ " -device pci-testdev,bus=noshpcbr,addr=1.0,acpi-index=301"
+ " -device pcie-root-port,id=hprp,port=0x0,chassis=1,addr=6.0"
+ " -device pci-testdev,bus=hprp,acpi-index=401"
+ " -device pcie-root-port,id=nohprp,port=0x0,chassis=2,hotplug=off,"
+ "addr=7.0"
+ " -device pci-testdev,bus=nohprp,acpi-index=501"
+ " -device pcie-root-port,id=nohprpint,port=0x0,chassis=3,hotplug=off,"
+ "multifunction=on,addr=8.0"
+ " -device pci-testdev,bus=nohprpint,acpi-index=601,addr=8.1"
+ " -device pcie-root-port,id=hprp2,port=0x0,chassis=4,bus=nohprpint,"
+ "addr=9.0"
+ " -device pci-testdev,bus=hprp2,acpi-index=602"
+ , &data);
+ free_test_data(&data);
+}
+
static void test_acpi_q35_multif_bridge(void)
{
test_data data = {
.machine = MACHINE_Q35,
.variant = ".multi-bridge",
};
-
- if (!qtest_has_device("pcie-root-port")) {
- g_test_skip("Device pcie-root-port is not available");
- goto out;
- }
-
test_vm_prepare("-S"
" -device virtio-balloon,id=balloon0,addr=0x4.0x2"
" -device pcie-root-port,id=rp0,multifunction=on,"
@@ -1025,9 +1054,14 @@ static void test_acpi_q35_multif_bridge(void)
" -device pcie-root-port,id=rphptgt2,port=0x0,chassis=6,addr=2.2"
" -device pcie-root-port,id=rphptgt3,port=0x0,chassis=7,addr=2.3"
" -device pci-testdev,bus=pcie.0,addr=2.4"
+ " -device pci-testdev,bus=pcie.0,addr=2.5,acpi-index=102"
" -device pci-testdev,bus=pcie.0,addr=5.0"
+ " -device pci-testdev,bus=pcie.0,addr=0xf.0,acpi-index=101"
" -device pci-testdev,bus=rp0,addr=0.0"
- " -device pci-testdev,bus=br1", &data);
+ " -device pci-testdev,bus=br1"
+ " -device pcie-root-port,id=rpnohp,chassis=8,addr=0xA.0,hotplug=off"
+ " -device pcie-root-port,id=rp3,chassis=9,bus=rpnohp"
+ , &data);
/* hotplugged bridges section */
qtest_qmp_device_add(data.qts, "pci-bridge", "hpbr1",
@@ -1049,7 +1083,6 @@ static void test_acpi_q35_multif_bridge(void)
/* check that reboot/reset doesn't change any ACPI tables */
qtest_qmp_send(data.qts, "{'execute':'system_reset' }");
process_acpi_tables(&data);
-out:
free_test_data(&data);
}
@@ -1403,11 +1436,6 @@ static void test_acpi_tcg_dimm_pxm(const char *machine)
{
test_data data;
- if (!qtest_has_device("nvdimm")) {
- g_test_skip("Device nvdimm is not available");
- return;
- }
-
memset(&data, 0, sizeof(data));
data.machine = machine;
data.variant = ".dimmpxm";
@@ -1456,11 +1484,6 @@ static void test_acpi_virt_tcg_memhp(void)
.scan_len = 256ULL * 1024 * 1024,
};
- if (!qtest_has_device("nvdimm")) {
- g_test_skip("Device nvdimm is not available");
- goto out;
- }
-
data.variant = ".memhp";
test_acpi_one(" -machine nvdimm=on"
" -cpu cortex-a57"
@@ -1474,7 +1497,7 @@ static void test_acpi_virt_tcg_memhp(void)
" -device pc-dimm,id=dimm0,memdev=ram2,node=0"
" -device nvdimm,id=dimm1,memdev=nvm0,node=1",
&data);
-out:
+
free_test_data(&data);
}
@@ -1492,11 +1515,6 @@ static void test_acpi_microvm_tcg(void)
{
test_data data;
- if (!qtest_has_device("virtio-blk-device")) {
- g_test_skip("Device virtio-blk-device is not available");
- return;
- }
-
test_acpi_microvm_prepare(&data);
test_acpi_one(" -machine microvm,acpi=on,ioapic2=off,rtc=off",
&data);
@@ -1507,11 +1525,6 @@ static void test_acpi_microvm_usb_tcg(void)
{
test_data data;
- if (!qtest_has_device("virtio-blk-device")) {
- g_test_skip("Device virtio-blk-device is not available");
- return;
- }
-
test_acpi_microvm_prepare(&data);
data.variant = ".usb";
test_acpi_one(" -machine microvm,acpi=on,ioapic2=off,usb=on,rtc=off",
@@ -1523,11 +1536,6 @@ static void test_acpi_microvm_rtc_tcg(void)
{
test_data data;
- if (!qtest_has_device("virtio-blk-device")) {
- g_test_skip("Device virtio-blk-device is not available");
- return;
- }
-
test_acpi_microvm_prepare(&data);
data.variant = ".rtc";
test_acpi_one(" -machine microvm,acpi=on,ioapic2=off,rtc=on",
@@ -1539,11 +1547,6 @@ static void test_acpi_microvm_pcie_tcg(void)
{
test_data data;
- if (!qtest_has_device("virtio-blk-device")) {
- g_test_skip("Device virtio-blk-device is not available");
- return;
- }
-
test_acpi_microvm_prepare(&data);
data.variant = ".pcie";
data.tcg_only = true; /* need constant host-phys-bits */
@@ -1556,11 +1559,6 @@ static void test_acpi_microvm_ioapic2_tcg(void)
{
test_data data;
- if (!qtest_has_device("virtio-blk-device")) {
- g_test_skip("Device virtio-blk-device is not available");
- return;
- }
-
test_acpi_microvm_prepare(&data);
data.variant = ".ioapic2";
test_acpi_one(" -machine microvm,acpi=on,ioapic2=on,rtc=off",
@@ -1600,12 +1598,6 @@ static void test_acpi_virt_tcg_pxb(void)
.ram_start = 0x40000000ULL,
.scan_len = 128ULL * 1024 * 1024,
};
-
- if (!qtest_has_device("pcie-root-port")) {
- g_test_skip("Device pcie-root-port is not available");
- goto out;
- }
-
/*
* While using -cdrom, the cdrom would auto plugged into pxb-pcie,
* the reason is the bus of pxb-pcie is also root bus, it would lead
@@ -1624,7 +1616,7 @@ static void test_acpi_virt_tcg_pxb(void)
" -cpu cortex-a57"
" -device pxb-pcie,bus_nr=128",
&data);
-out:
+
free_test_data(&data);
}
@@ -1812,12 +1804,6 @@ static void test_acpi_microvm_acpi_erst(void)
gchar *params;
test_data data;
- if (!qtest_has_device("virtio-blk-device")) {
- g_test_skip("Device virtio-blk-device is not available");
- g_free(tmp_path);
- return;
- }
-
test_acpi_microvm_prepare(&data);
data.variant = ".pcie";
data.tcg_only = true; /* need constant host-phys-bits */
@@ -1878,11 +1864,6 @@ static void test_acpi_q35_viot(void)
.variant = ".viot",
};
- if (!qtest_has_device("virtio-iommu")) {
- g_test_skip("Device virtio-iommu is not available");
- goto out;
- }
-
/*
* To keep things interesting, two buses bypass the IOMMU.
* VIOT should only describes the other two buses.
@@ -1893,7 +1874,6 @@ static void test_acpi_q35_viot(void)
"-device pxb-pcie,bus_nr=0x20,id=pcie.200,bus=pcie.0,bypass_iommu=on "
"-device pxb-pcie,bus_nr=0x30,id=pcie.300,bus=pcie.0",
&data);
-out:
free_test_data(&data);
}
@@ -1954,10 +1934,8 @@ static void test_acpi_virt_viot(void)
.scan_len = 128ULL * 1024 * 1024,
};
- if (qtest_has_device("virtio-iommu")) {
- test_acpi_one("-cpu cortex-a57 "
- "-device virtio-iommu-pci", &data);
- }
+ test_acpi_one("-cpu cortex-a57 "
+ "-device virtio-iommu-pci", &data);
free_test_data(&data);
}
@@ -2066,11 +2044,6 @@ static void test_acpi_microvm_oem_fields(void)
test_data data;
char *args;
- if (!qtest_has_device("virtio-blk-device")) {
- g_test_skip("Device virtio-blk-device is not available");
- return;
- }
-
test_acpi_microvm_prepare(&data);
args = test_acpi_create_args(&data,
@@ -2161,6 +2134,8 @@ int main(int argc, char *argv[])
test_acpi_q35_tcg_tpm12_tis);
}
qtest_add_func("acpi/q35/bridge", test_acpi_q35_tcg_bridge);
+ qtest_add_func("acpi/q35/no-acpi-hotplug",
+ test_acpi_q35_tcg_no_acpi_hotplug);
qtest_add_func("acpi/q35/multif-bridge",
test_acpi_q35_multif_bridge);
qtest_add_func("acpi/q35/mmio64", test_acpi_q35_tcg_mmio64);
diff --git a/tests/qtest/e1000e-test.c b/tests/qtest/e1000e-test.c
index b63a4d3..de9738f 100644
--- a/tests/qtest/e1000e-test.c
+++ b/tests/qtest/e1000e-test.c
@@ -27,6 +27,7 @@
#include "qemu/osdep.h"
#include "libqtest-single.h"
#include "libqos/pci-pc.h"
+#include "net/eth.h"
#include "qemu/sockets.h"
#include "qemu/iov.h"
#include "qemu/module.h"
@@ -35,9 +36,13 @@
#include "libqos/e1000e.h"
#include "hw/net/e1000_regs.h"
+static const struct eth_header packet = {
+ .h_dest = E1000E_ADDRESS,
+ .h_source = E1000E_ADDRESS,
+};
+
static void e1000e_send_verify(QE1000E *d, int *test_sockets, QGuestAllocator *alloc)
{
- static const char test[] = "TEST";
struct e1000_tx_desc descr;
char buffer[64];
int ret;
@@ -45,7 +50,7 @@ static void e1000e_send_verify(QE1000E *d, int *test_sockets, QGuestAllocator *a
/* Prepare test data buffer */
uint64_t data = guest_alloc(alloc, sizeof(buffer));
- memwrite(data, test, sizeof(test));
+ memwrite(data, &packet, sizeof(packet));
/* Prepare TX descriptor */
memset(&descr, 0, sizeof(descr));
@@ -71,7 +76,7 @@ static void e1000e_send_verify(QE1000E *d, int *test_sockets, QGuestAllocator *a
g_assert_cmpint(ret, == , sizeof(recv_len));
ret = recv(test_sockets[0], buffer, sizeof(buffer), 0);
g_assert_cmpint(ret, ==, sizeof(buffer));
- g_assert_cmpstr(buffer, == , test);
+ g_assert_false(memcmp(buffer, &packet, sizeof(packet)));
/* Free test data buffer */
guest_free(alloc, data);
@@ -81,15 +86,15 @@ static void e1000e_receive_verify(QE1000E *d, int *test_sockets, QGuestAllocator
{
union e1000_rx_desc_extended descr;
- char test[] = "TEST";
- int len = htonl(sizeof(test));
+ struct eth_header test_iov = packet;
+ int len = htonl(sizeof(packet));
struct iovec iov[] = {
{
.iov_base = &len,
.iov_len = sizeof(len),
},{
- .iov_base = test,
- .iov_len = sizeof(test),
+ .iov_base = &test_iov,
+ .iov_len = sizeof(packet),
},
};
@@ -97,8 +102,8 @@ static void e1000e_receive_verify(QE1000E *d, int *test_sockets, QGuestAllocator
int ret;
/* Send a dummy packet to device's socket*/
- ret = iov_send(test_sockets[0], iov, 2, 0, sizeof(len) + sizeof(test));
- g_assert_cmpint(ret, == , sizeof(test) + sizeof(len));
+ ret = iov_send(test_sockets[0], iov, 2, 0, sizeof(len) + sizeof(packet));
+ g_assert_cmpint(ret, == , sizeof(packet) + sizeof(len));
/* Prepare test data buffer */
uint64_t data = guest_alloc(alloc, sizeof(buffer));
@@ -119,7 +124,7 @@ static void e1000e_receive_verify(QE1000E *d, int *test_sockets, QGuestAllocator
/* Check data sent to the backend */
memread(data, buffer, sizeof(buffer));
- g_assert_cmpstr(buffer, == , test);
+ g_assert_false(memcmp(buffer, &packet, sizeof(packet)));
/* Free test data buffer */
guest_free(alloc, data);
diff --git a/tests/qtest/fuzz/generic_fuzz_configs.h b/tests/qtest/fuzz/generic_fuzz_configs.h
index a825b78..50689da 100644
--- a/tests/qtest/fuzz/generic_fuzz_configs.h
+++ b/tests/qtest/fuzz/generic_fuzz_configs.h
@@ -91,6 +91,11 @@ const generic_fuzz_config predefined_configs[] = {
"-device e1000e,netdev=net0 -netdev user,id=net0",
.objects = "e1000e",
},{
+ .name = "igb",
+ .args = "-M q35 -nodefaults "
+ "-device igb,netdev=net0 -netdev user,id=net0",
+ .objects = "igb",
+ },{
.name = "cirrus-vga",
.args = "-machine q35 -nodefaults -device cirrus-vga",
.objects = "cirrus*",
diff --git a/tests/qtest/igb-test.c b/tests/qtest/igb-test.c
new file mode 100644
index 0000000..3d397ea
--- /dev/null
+++ b/tests/qtest/igb-test.c
@@ -0,0 +1,256 @@
+/*
+ * QTest testcase for igb NIC
+ *
+ * Copyright (c) 2022-2023 Red Hat, Inc.
+ * Copyright (c) 2015 Ravello Systems LTD (http://ravellosystems.com)
+ * Developed by Daynix Computing LTD (http://www.daynix.com)
+ *
+ * Authors:
+ * Akihiko Odaki <akihiko.odaki@daynix.com>
+ * Dmitry Fleytman <dmitry@daynix.com>
+ * Leonid Bloch <leonid@daynix.com>
+ * Yan Vugenfirer <yan@daynix.com>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, see <http://www.gnu.org/licenses/>.
+ */
+
+
+#include "qemu/osdep.h"
+#include "libqtest-single.h"
+#include "libqos/pci-pc.h"
+#include "net/eth.h"
+#include "qemu/sockets.h"
+#include "qemu/iov.h"
+#include "qemu/module.h"
+#include "qemu/bitops.h"
+#include "libqos/libqos-malloc.h"
+#include "libqos/e1000e.h"
+#include "hw/net/igb_regs.h"
+
+#ifndef _WIN32
+
+static const struct eth_header packet = {
+ .h_dest = E1000E_ADDRESS,
+ .h_source = E1000E_ADDRESS,
+};
+
+static void igb_send_verify(QE1000E *d, int *test_sockets, QGuestAllocator *alloc)
+{
+ union e1000_adv_tx_desc descr;
+ char buffer[64];
+ int ret;
+ uint32_t recv_len;
+
+ /* Prepare test data buffer */
+ uint64_t data = guest_alloc(alloc, sizeof(buffer));
+ memwrite(data, &packet, sizeof(packet));
+
+ /* Prepare TX descriptor */
+ memset(&descr, 0, sizeof(descr));
+ descr.read.buffer_addr = cpu_to_le64(data);
+ descr.read.cmd_type_len = cpu_to_le32(E1000_TXD_CMD_RS |
+ E1000_TXD_CMD_EOP |
+ E1000_TXD_DTYP_D |
+ sizeof(buffer));
+
+ /* Put descriptor to the ring */
+ e1000e_tx_ring_push(d, &descr);
+
+ /* Wait for TX WB interrupt */
+ e1000e_wait_isr(d, E1000E_TX0_MSG_ID);
+
+ /* Check DD bit */
+ g_assert_cmphex(le32_to_cpu(descr.wb.status) & E1000_TXD_STAT_DD, ==,
+ E1000_TXD_STAT_DD);
+
+ /* Check data sent to the backend */
+ ret = recv(test_sockets[0], &recv_len, sizeof(recv_len), 0);
+ g_assert_cmpint(ret, == , sizeof(recv_len));
+ ret = recv(test_sockets[0], buffer, sizeof(buffer), 0);
+ g_assert_cmpint(ret, ==, sizeof(buffer));
+ g_assert_false(memcmp(buffer, &packet, sizeof(packet)));
+
+ /* Free test data buffer */
+ guest_free(alloc, data);
+}
+
+static void igb_receive_verify(QE1000E *d, int *test_sockets, QGuestAllocator *alloc)
+{
+ union e1000_adv_rx_desc descr;
+
+ struct eth_header test_iov = packet;
+ int len = htonl(sizeof(packet));
+ struct iovec iov[] = {
+ {
+ .iov_base = &len,
+ .iov_len = sizeof(len),
+ },{
+ .iov_base = &test_iov,
+ .iov_len = sizeof(packet),
+ },
+ };
+
+ char buffer[64];
+ int ret;
+
+ /* Send a dummy packet to device's socket*/
+ ret = iov_send(test_sockets[0], iov, 2, 0, sizeof(len) + sizeof(packet));
+ g_assert_cmpint(ret, == , sizeof(packet) + sizeof(len));
+
+ /* Prepare test data buffer */
+ uint64_t data = guest_alloc(alloc, sizeof(buffer));
+
+ /* Prepare RX descriptor */
+ memset(&descr, 0, sizeof(descr));
+ descr.read.pkt_addr = cpu_to_le64(data);
+
+ /* Put descriptor to the ring */
+ e1000e_rx_ring_push(d, &descr);
+
+ /* Wait for TX WB interrupt */
+ e1000e_wait_isr(d, E1000E_RX0_MSG_ID);
+
+ /* Check DD bit */
+ g_assert_cmphex(le32_to_cpu(descr.wb.upper.status_error) &
+ E1000_RXD_STAT_DD, ==, E1000_RXD_STAT_DD);
+
+ /* Check data sent to the backend */
+ memread(data, buffer, sizeof(buffer));
+ g_assert_false(memcmp(buffer, &packet, sizeof(packet)));
+
+ /* Free test data buffer */
+ guest_free(alloc, data);
+}
+
+static void test_e1000e_init(void *obj, void *data, QGuestAllocator * alloc)
+{
+ /* init does nothing */
+}
+
+static void test_igb_tx(void *obj, void *data, QGuestAllocator * alloc)
+{
+ 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;
+ }
+
+ igb_send_verify(d, data, alloc);
+}
+
+static void test_igb_rx(void *obj, void *data, QGuestAllocator * alloc)
+{
+ 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;
+ }
+
+ igb_receive_verify(d, data, alloc);
+}
+
+static void test_igb_multiple_transfers(void *obj, void *data,
+ QGuestAllocator *alloc)
+{
+ static const long iterations = 4 * 1024;
+ long i;
+
+ 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;
+ }
+
+ for (i = 0; i < iterations; i++) {
+ igb_send_verify(d, data, alloc);
+ igb_receive_verify(d, data, alloc);
+ }
+
+}
+
+static void data_test_clear(void *sockets)
+{
+ int *test_sockets = sockets;
+
+ close(test_sockets[0]);
+ qos_invalidate_command_line();
+ close(test_sockets[1]);
+ g_free(test_sockets);
+}
+
+static void *data_test_init(GString *cmd_line, void *arg)
+{
+ int *test_sockets = g_new(int, 2);
+ int ret = socketpair(PF_UNIX, SOCK_STREAM, 0, test_sockets);
+ g_assert_cmpint(ret, != , -1);
+
+ g_string_append_printf(cmd_line, " -netdev socket,fd=%d,id=hs0 ",
+ test_sockets[1]);
+
+ g_test_queue_destroy(data_test_clear, test_sockets);
+ return test_sockets;
+}
+
+#endif
+
+static void *data_test_init_no_socket(GString *cmd_line, void *arg)
+{
+ g_string_append(cmd_line, " -netdev hubport,hubid=0,id=hs0 ");
+ return arg;
+}
+
+static void test_igb_hotplug(void *obj, void *data, QGuestAllocator * alloc)
+{
+ QTestState *qts = global_qtest; /* TODO: get rid of global_qtest here */
+ QE1000E_PCI *dev = obj;
+
+ if (dev->pci_dev.bus->not_hotpluggable) {
+ g_test_skip("pci bus does not support hotplug");
+ return;
+ }
+
+ qtest_qmp_device_add(qts, "igb", "igb_net", "{'addr': '0x06'}");
+ qpci_unplug_acpi_device_test(qts, "igb_net", 0x06);
+}
+
+static void register_igb_test(void)
+{
+ QOSGraphTestOptions opts = { 0 };
+
+#ifndef _WIN32
+ opts.before = data_test_init,
+ qos_add_test("init", "igb", test_e1000e_init, &opts);
+ qos_add_test("tx", "igb", test_igb_tx, &opts);
+ qos_add_test("rx", "igb", test_igb_rx, &opts);
+ qos_add_test("multiple_transfers", "igb",
+ test_igb_multiple_transfers, &opts);
+#endif
+
+ opts.before = data_test_init_no_socket;
+ qos_add_test("hotplug", "igb", test_igb_hotplug, &opts);
+}
+
+libqos_init(register_igb_test);
diff --git a/tests/qtest/libqos/e1000e.c b/tests/qtest/libqos/e1000e.c
index 28fb305..925654c 100644
--- a/tests/qtest/libqos/e1000e.c
+++ b/tests/qtest/libqos/e1000e.c
@@ -36,18 +36,6 @@
#define E1000E_RING_LEN (0x1000)
-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)
{
QE1000E_PCI *d_pci = container_of(d, QE1000E_PCI, e1000e);
diff --git a/tests/qtest/libqos/e1000e.h b/tests/qtest/libqos/e1000e.h
index 091ce13..30643c8 100644
--- a/tests/qtest/libqos/e1000e.h
+++ b/tests/qtest/libqos/e1000e.h
@@ -25,6 +25,8 @@
#define E1000E_RX0_MSG_ID (0)
#define E1000E_TX0_MSG_ID (1)
+#define E1000E_ADDRESS { 0x52, 0x54, 0x00, 0x12, 0x34, 0x56 }
+
typedef struct QE1000E QE1000E;
typedef struct QE1000E_PCI QE1000E_PCI;
@@ -40,6 +42,18 @@ struct QE1000E_PCI {
QE1000E e1000e;
};
+static inline 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 inline 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_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);
diff --git a/tests/qtest/libqos/igb.c b/tests/qtest/libqos/igb.c
new file mode 100644
index 0000000..12fb531
--- /dev/null
+++ b/tests/qtest/libqos/igb.c
@@ -0,0 +1,185 @@
+/*
+ * libqos driver framework
+ *
+ * Copyright (c) 2022-2023 Red Hat, Inc.
+ * 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.1 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 "hw/net/igb_regs.h"
+#include "hw/net/mii.h"
+#include "hw/pci/pci_ids.h"
+#include "../libqtest.h"
+#include "pci-pc.h"
+#include "qemu/sockets.h"
+#include "qemu/iov.h"
+#include "qemu/module.h"
+#include "qemu/bitops.h"
+#include "libqos-malloc.h"
+#include "qgraph.h"
+#include "e1000e.h"
+
+#define IGB_IVAR_TEST_CFG \
+ ((E1000E_RX0_MSG_ID | E1000_IVAR_VALID) << (igb_ivar_entry_rx(0) * 8) | \
+ ((E1000E_TX0_MSG_ID | E1000_IVAR_VALID) << (igb_ivar_entry_tx(0) * 8)))
+
+#define E1000E_RING_LEN (0x1000)
+
+static void e1000e_foreach_callback(QPCIDevice *dev, int devfn, void *data)
+{
+ QPCIDevice *res = data;
+ memcpy(res, dev, sizeof(QPCIDevice));
+ g_free(dev);
+}
+
+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 igb_pci_start_hw(QOSGraphObject *obj)
+{
+ static const uint8_t address[] = E1000E_ADDRESS;
+ 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, E1000_CTRL);
+ e1000e_macreg_write(&d->e1000e, E1000_CTRL, val | E1000_CTRL_RST | E1000_CTRL_SLU);
+
+ /* Setup link */
+ e1000e_macreg_write(&d->e1000e, E1000_MDIC,
+ MII_BMCR_AUTOEN | MII_BMCR_ANRESTART |
+ (MII_BMCR << E1000_MDIC_REG_SHIFT) |
+ (1 << E1000_MDIC_PHY_SHIFT) |
+ E1000_MDIC_OP_WRITE);
+
+ qtest_clock_step(d->pci_dev.bus->qts, 900000000);
+
+ /* Enable and configure MSI-X */
+ qpci_msix_enable(&d->pci_dev);
+ e1000e_macreg_write(&d->e1000e, E1000_IVAR0, IGB_IVAR_TEST_CFG);
+
+ /* Check the device link status */
+ val = e1000e_macreg_read(&d->e1000e, E1000_STATUS);
+ g_assert_cmphex(val & E1000_STATUS_LU, ==, E1000_STATUS_LU);
+
+ /* Initialize TX/RX logic */
+ e1000e_macreg_write(&d->e1000e, E1000_RCTL, 0);
+ e1000e_macreg_write(&d->e1000e, E1000_TCTL, 0);
+
+ e1000e_macreg_write(&d->e1000e, E1000_TDBAL(0),
+ (uint32_t) d->e1000e.tx_ring);
+ e1000e_macreg_write(&d->e1000e, E1000_TDBAH(0),
+ (uint32_t) (d->e1000e.tx_ring >> 32));
+ e1000e_macreg_write(&d->e1000e, E1000_TDLEN(0), E1000E_RING_LEN);
+ e1000e_macreg_write(&d->e1000e, E1000_TDT(0), 0);
+ e1000e_macreg_write(&d->e1000e, E1000_TDH(0), 0);
+
+ /* Enable transmit */
+ e1000e_macreg_write(&d->e1000e, E1000_TCTL, E1000_TCTL_EN);
+
+ e1000e_macreg_write(&d->e1000e, E1000_RDBAL(0),
+ (uint32_t)d->e1000e.rx_ring);
+ e1000e_macreg_write(&d->e1000e, E1000_RDBAH(0),
+ (uint32_t)(d->e1000e.rx_ring >> 32));
+ e1000e_macreg_write(&d->e1000e, E1000_RDLEN(0), E1000E_RING_LEN);
+ e1000e_macreg_write(&d->e1000e, E1000_RDT(0), 0);
+ e1000e_macreg_write(&d->e1000e, E1000_RDH(0), 0);
+ e1000e_macreg_write(&d->e1000e, E1000_RA,
+ le32_to_cpu(*(uint32_t *)address));
+ e1000e_macreg_write(&d->e1000e, E1000_RA + 4,
+ E1000_RAH_AV | E1000_RAH_POOL_1 |
+ le16_to_cpu(*(uint16_t *)(address + 4)));
+
+ /* Enable receive */
+ e1000e_macreg_write(&d->e1000e, E1000_RFCTL, E1000_RFCTL_EXTEN);
+ e1000e_macreg_write(&d->e1000e, E1000_RCTL, E1000_RCTL_EN);
+
+ /* Enable all interrupts */
+ e1000e_macreg_write(&d->e1000e, E1000_IMS, 0xFFFFFFFF);
+ e1000e_macreg_write(&d->e1000e, E1000_EIMS, 0xFFFFFFFF);
+
+}
+
+static void *igb_pci_get_driver(void *obj, const char *interface)
+{
+ QE1000E_PCI *epci = obj;
+ if (!g_strcmp0(interface, "igb-if")) {
+ return &epci->e1000e;
+ }
+
+ /* implicit contains */
+ if (!g_strcmp0(interface, "pci-device")) {
+ return &epci->pci_dev;
+ }
+
+ fprintf(stderr, "%s not present in igb\n", interface);
+ g_assert_not_reached();
+}
+
+static void *igb_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 = igb_pci_get_driver;
+ d->obj.start_hw = igb_pci_start_hw;
+ d->obj.destructor = e1000e_pci_destructor;
+
+ return &d->obj;
+}
+
+static void igb_register_nodes(void)
+{
+ QPCIAddress addr = {
+ .vendor_id = PCI_VENDOR_ID_INTEL,
+ .device_id = E1000_DEV_ID_82576,
+ };
+
+ /*
+ * 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("igb", igb_pci_create);
+ qos_node_consumes("igb", "pci-bus", &opts);
+}
+
+libqos_init(igb_register_nodes);
diff --git a/tests/qtest/libqos/meson.build b/tests/qtest/libqos/meson.build
index 32f0288..cc209a8 100644
--- a/tests/qtest/libqos/meson.build
+++ b/tests/qtest/libqos/meson.build
@@ -30,6 +30,7 @@ libqos_srcs = files(
'i2c.c',
'i2c-imx.c',
'i2c-omap.c',
+ 'igb.c',
'sdhci.c',
'tpci200.c',
'virtio.c',
diff --git a/tests/qtest/meson.build b/tests/qtest/meson.build
index 62eecf2..c9292b6 100644
--- a/tests/qtest/meson.build
+++ b/tests/qtest/meson.build
@@ -259,6 +259,7 @@ qos_test_ss.add(
'virtio-scsi-test.c',
'virtio-iommu-test.c',
'vmxnet3-test.c',
+ 'igb-test.c',
)
if config_all_devices.has_key('CONFIG_VIRTIO_SERIAL')
diff --git a/tests/tcg/hexagon/Makefile.target b/tests/tcg/hexagon/Makefile.target
index 18e6a59..0d82dfa 100644
--- a/tests/tcg/hexagon/Makefile.target
+++ b/tests/tcg/hexagon/Makefile.target
@@ -1,5 +1,5 @@
##
-## Copyright(c) 2019-2022 Qualcomm Innovation Center, Inc. All Rights Reserved.
+## Copyright(c) 2019-2023 Qualcomm Innovation Center, Inc. All Rights Reserved.
##
## This program is free software; you can redistribute it and/or modify
## it under the terms of the GNU General Public License as published by
@@ -45,6 +45,10 @@ HEX_TESTS += fpstuff
HEX_TESTS += overflow
HEX_TESTS += signal_context
HEX_TESTS += reg_mut
+HEX_TESTS += vector_add_int
+HEX_TESTS += scatter_gather
+HEX_TESTS += hvx_misc
+HEX_TESTS += hvx_histogram
HEX_TESTS += test_abs
HEX_TESTS += test_bitcnt
@@ -78,3 +82,10 @@ TESTS += $(HEX_TESTS)
usr: usr.c
$(CC) $(CFLAGS) -mv67t -O2 -Wno-inline-asm -Wno-expansion-to-defined $< -o $@ $(LDFLAGS)
+scatter_gather: CFLAGS += -mhvx
+vector_add_int: CFLAGS += -mhvx -fvectorize
+hvx_misc: CFLAGS += -mhvx
+hvx_histogram: CFLAGS += -mhvx -Wno-gnu-folding-constant
+
+hvx_histogram: hvx_histogram.c hvx_histogram_row.S
+ $(CC) $(CFLAGS) $(CROSS_CC_GUEST_CFLAGS) $^ -o $@ $(LDFLAGS)
diff --git a/tests/tcg/hexagon/fpstuff.c b/tests/tcg/hexagon/fpstuff.c
index 56bf562..90ce9a6 100644
--- a/tests/tcg/hexagon/fpstuff.c
+++ b/tests/tcg/hexagon/fpstuff.c
@@ -1,5 +1,5 @@
/*
- * Copyright(c) 2020-2022 Qualcomm Innovation Center, Inc. All Rights Reserved.
+ * Copyright(c) 2020-2023 Qualcomm Innovation Center, Inc. All Rights Reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -40,6 +40,7 @@ const int SF_HEX_NAN = 0xffffffff;
const int SF_small_neg = 0xab98fba8;
const int SF_denorm = 0x00000001;
const int SF_random = 0x346001d6;
+const int SF_neg_zero = 0x80000000;
const long long DF_QNaN = 0x7ff8000000000000ULL;
const long long DF_SNaN = 0x7ff7000000000000ULL;
@@ -536,6 +537,33 @@ static void check_sffixupd(void)
check32(result, 0x146001d6);
}
+static void check_sffms(void)
+{
+ int result;
+
+ /* Check that sffms properly deals with -0 */
+ result = SF_neg_zero;
+ asm ("%0 -= sfmpy(%1 , %2)\n\t"
+ : "+r"(result)
+ : "r"(SF_ZERO), "r"(SF_ZERO)
+ : "r12", "r8");
+ check32(result, SF_neg_zero);
+
+ result = SF_ZERO;
+ asm ("%0 -= sfmpy(%1 , %2)\n\t"
+ : "+r"(result)
+ : "r"(SF_neg_zero), "r"(SF_ZERO)
+ : "r12", "r8");
+ check32(result, SF_ZERO);
+
+ result = SF_ZERO;
+ asm ("%0 -= sfmpy(%1 , %2)\n\t"
+ : "+r"(result)
+ : "r"(SF_ZERO), "r"(SF_neg_zero)
+ : "r12", "r8");
+ check32(result, SF_ZERO);
+}
+
static void check_float2int_convs()
{
int res32;
@@ -688,6 +716,7 @@ int main()
check_invsqrta();
check_sffixupn();
check_sffixupd();
+ check_sffms();
check_float2int_convs();
puts(err ? "FAIL" : "PASS");
diff --git a/tests/tcg/hexagon/preg_alias.c b/tests/tcg/hexagon/preg_alias.c
index b44a811..8798fbc 100644
--- a/tests/tcg/hexagon/preg_alias.c
+++ b/tests/tcg/hexagon/preg_alias.c
@@ -1,5 +1,5 @@
/*
- * Copyright(c) 2019-2022 Qualcomm Innovation Center, Inc. All Rights Reserved.
+ * Copyright(c) 2019-2023 Qualcomm Innovation Center, Inc. All Rights Reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -65,7 +65,7 @@ static inline void creg_alias(int cval, PRegs *pregs)
: "=r"(pregs->pregs.p0), "=r"(pregs->pregs.p1),
"=r"(pregs->pregs.p2), "=r"(pregs->pregs.p3)
: "r"(cval)
- : "p0", "p1", "p2", "p3");
+ : "c4", "p0", "p1", "p2", "p3");
}
int err;
@@ -92,7 +92,7 @@ static inline void creg_alias_pair(unsigned int cval, PRegs *pregs)
: "=r"(pregs->pregs.p0), "=r"(pregs->pregs.p1),
"=r"(pregs->pregs.p2), "=r"(pregs->pregs.p3), "=r"(c5)
: "r"(cval_pair)
- : "p0", "p1", "p2", "p3");
+ : "c4", "c5", "p0", "p1", "p2", "p3");
check(c5, 0xdeadbeef);
}
@@ -117,7 +117,7 @@ static void test_packet(void)
"}\n\t"
: "+r"(result)
: "r"(0xffffffff), "r"(0xff00ffff), "r"(0x837ed653)
- : "p0", "p1", "p2", "p3");
+ : "c4", "p0", "p1", "p2", "p3");
check(result, old_val);
/* Test a predicated store */
@@ -129,7 +129,7 @@ static void test_packet(void)
"}\n\t"
:
: "r"(0), "r"(0xffffffff), "r"(&result)
- : "p0", "p1", "p2", "p3", "memory");
+ : "c4", "p0", "p1", "p2", "p3", "memory");
check(result, 0x0);
}
diff --git a/tests/tcg/hexagon/scatter_gather.c b/tests/tcg/hexagon/scatter_gather.c
index b93eb18..bf8b5e0 100644
--- a/tests/tcg/hexagon/scatter_gather.c
+++ b/tests/tcg/hexagon/scatter_gather.c
@@ -1,5 +1,5 @@
/*
- * Copyright(c) 2019-2021 Qualcomm Innovation Center, Inc. All Rights Reserved.
+ * Copyright(c) 2019-2023 Qualcomm Innovation Center, Inc. All Rights Reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -40,47 +40,6 @@ typedef long HVX_VectorPair __attribute__((__vector_size__(256)))
typedef long HVX_VectorPred __attribute__((__vector_size__(128)))
__attribute__((aligned(128)));
-#define VSCATTER_16(BASE, RGN, OFF, VALS) \
- __builtin_HEXAGON_V6_vscattermh_128B((int)BASE, RGN, OFF, VALS)
-#define VSCATTER_16_MASKED(MASK, BASE, RGN, OFF, VALS) \
- __builtin_HEXAGON_V6_vscattermhq_128B(MASK, (int)BASE, RGN, OFF, VALS)
-#define VSCATTER_32(BASE, RGN, OFF, VALS) \
- __builtin_HEXAGON_V6_vscattermw_128B((int)BASE, RGN, OFF, VALS)
-#define VSCATTER_32_MASKED(MASK, BASE, RGN, OFF, VALS) \
- __builtin_HEXAGON_V6_vscattermwq_128B(MASK, (int)BASE, RGN, OFF, VALS)
-#define VSCATTER_16_32(BASE, RGN, OFF, VALS) \
- __builtin_HEXAGON_V6_vscattermhw_128B((int)BASE, RGN, OFF, VALS)
-#define VSCATTER_16_32_MASKED(MASK, BASE, RGN, OFF, VALS) \
- __builtin_HEXAGON_V6_vscattermhwq_128B(MASK, (int)BASE, RGN, OFF, VALS)
-#define VSCATTER_16_ACC(BASE, RGN, OFF, VALS) \
- __builtin_HEXAGON_V6_vscattermh_add_128B((int)BASE, RGN, OFF, VALS)
-#define VSCATTER_32_ACC(BASE, RGN, OFF, VALS) \
- __builtin_HEXAGON_V6_vscattermw_add_128B((int)BASE, RGN, OFF, VALS)
-#define VSCATTER_16_32_ACC(BASE, RGN, OFF, VALS) \
- __builtin_HEXAGON_V6_vscattermhw_add_128B((int)BASE, RGN, OFF, VALS)
-
-#define VGATHER_16(DSTADDR, BASE, RGN, OFF) \
- __builtin_HEXAGON_V6_vgathermh_128B(DSTADDR, (int)BASE, RGN, OFF)
-#define VGATHER_16_MASKED(DSTADDR, MASK, BASE, RGN, OFF) \
- __builtin_HEXAGON_V6_vgathermhq_128B(DSTADDR, MASK, (int)BASE, RGN, OFF)
-#define VGATHER_32(DSTADDR, BASE, RGN, OFF) \
- __builtin_HEXAGON_V6_vgathermw_128B(DSTADDR, (int)BASE, RGN, OFF)
-#define VGATHER_32_MASKED(DSTADDR, MASK, BASE, RGN, OFF) \
- __builtin_HEXAGON_V6_vgathermwq_128B(DSTADDR, MASK, (int)BASE, RGN, OFF)
-#define VGATHER_16_32(DSTADDR, BASE, RGN, OFF) \
- __builtin_HEXAGON_V6_vgathermhw_128B(DSTADDR, (int)BASE, RGN, OFF)
-#define VGATHER_16_32_MASKED(DSTADDR, MASK, BASE, RGN, OFF) \
- __builtin_HEXAGON_V6_vgathermhwq_128B(DSTADDR, MASK, (int)BASE, RGN, OFF)
-
-#define VSHUFF_H(V) \
- __builtin_HEXAGON_V6_vshuffh_128B(V)
-#define VSPLAT_H(X) \
- __builtin_HEXAGON_V6_lvsplath_128B(X)
-#define VAND_VAL(PRED, VAL) \
- __builtin_HEXAGON_V6_vandvrt_128B(PRED, VAL)
-#define VDEAL_H(V) \
- __builtin_HEXAGON_V6_vdealh_128B(V)
-
int err;
/* define the number of rows/cols in a square matrix */
@@ -108,22 +67,22 @@ unsigned short vscatter16_32_ref[SCATTER_BUFFER_SIZE];
unsigned short vgather16_32_ref[MATRIX_SIZE];
/* declare the arrays of offsets */
-unsigned short half_offsets[MATRIX_SIZE];
-unsigned int word_offsets[MATRIX_SIZE];
+unsigned short half_offsets[MATRIX_SIZE] __attribute__((aligned(128)));
+unsigned int word_offsets[MATRIX_SIZE] __attribute__((aligned(128)));
/* declare the arrays of values */
-unsigned short half_values[MATRIX_SIZE];
-unsigned short half_values_acc[MATRIX_SIZE];
-unsigned short half_values_masked[MATRIX_SIZE];
-unsigned int word_values[MATRIX_SIZE];
-unsigned int word_values_acc[MATRIX_SIZE];
-unsigned int word_values_masked[MATRIX_SIZE];
+unsigned short half_values[MATRIX_SIZE] __attribute__((aligned(128)));
+unsigned short half_values_acc[MATRIX_SIZE] __attribute__((aligned(128)));
+unsigned short half_values_masked[MATRIX_SIZE] __attribute__((aligned(128)));
+unsigned int word_values[MATRIX_SIZE] __attribute__((aligned(128)));
+unsigned int word_values_acc[MATRIX_SIZE] __attribute__((aligned(128)));
+unsigned int word_values_masked[MATRIX_SIZE] __attribute__((aligned(128)));
/* declare the arrays of predicates */
-unsigned short half_predicates[MATRIX_SIZE];
-unsigned int word_predicates[MATRIX_SIZE];
+unsigned short half_predicates[MATRIX_SIZE] __attribute__((aligned(128)));
+unsigned int word_predicates[MATRIX_SIZE] __attribute__((aligned(128)));
-/* make this big enough for all the intrinsics */
+/* make this big enough for all the operations */
const size_t region_len = sizeof(vtcm);
/* optionally add sync instructions */
@@ -261,164 +220,201 @@ void create_offsets_values_preds_16_32(void)
}
}
-/* scatter the 16 bit elements using intrinsics */
+/* scatter the 16 bit elements using HVX */
void vector_scatter_16(void)
{
- /* copy the offsets and values to vectors */
- HVX_Vector offsets = *(HVX_Vector *)half_offsets;
- HVX_Vector values = *(HVX_Vector *)half_values;
-
- VSCATTER_16(&vtcm.vscatter16, region_len, offsets, values);
+ asm ("m0 = %1\n\t"
+ "v0 = vmem(%2 + #0)\n\t"
+ "v1 = vmem(%3 + #0)\n\t"
+ "vscatter(%0, m0, v0.h).h = v1\n\t"
+ : : "r"(vtcm.vscatter16), "r"(region_len),
+ "r"(half_offsets), "r"(half_values)
+ : "m0", "v0", "v1", "memory");
sync_scatter(vtcm.vscatter16);
}
-/* scatter-accumulate the 16 bit elements using intrinsics */
+/* scatter-accumulate the 16 bit elements using HVX */
void vector_scatter_16_acc(void)
{
- /* copy the offsets and values to vectors */
- HVX_Vector offsets = *(HVX_Vector *)half_offsets;
- HVX_Vector values = *(HVX_Vector *)half_values_acc;
-
- VSCATTER_16_ACC(&vtcm.vscatter16, region_len, offsets, values);
+ asm ("m0 = %1\n\t"
+ "v0 = vmem(%2 + #0)\n\t"
+ "v1 = vmem(%3 + #0)\n\t"
+ "vscatter(%0, m0, v0.h).h += v1\n\t"
+ : : "r"(vtcm.vscatter16), "r"(region_len),
+ "r"(half_offsets), "r"(half_values_acc)
+ : "m0", "v0", "v1", "memory");
sync_scatter(vtcm.vscatter16);
}
-/* scatter the 16 bit elements using intrinsics */
+/* masked scatter the 16 bit elements using HVX */
void vector_scatter_16_masked(void)
{
- /* copy the offsets and values to vectors */
- HVX_Vector offsets = *(HVX_Vector *)half_offsets;
- HVX_Vector values = *(HVX_Vector *)half_values_masked;
- HVX_Vector pred_reg = *(HVX_Vector *)half_predicates;
- HVX_VectorPred preds = VAND_VAL(pred_reg, ~0);
-
- VSCATTER_16_MASKED(preds, &vtcm.vscatter16, region_len, offsets, values);
+ asm ("r1 = #-1\n\t"
+ "v0 = vmem(%0 + #0)\n\t"
+ "q0 = vand(v0, r1)\n\t"
+ "m0 = %2\n\t"
+ "v0 = vmem(%3 + #0)\n\t"
+ "v1 = vmem(%4 + #0)\n\t"
+ "if (q0) vscatter(%1, m0, v0.h).h = v1\n\t"
+ : : "r"(half_predicates), "r"(vtcm.vscatter16), "r"(region_len),
+ "r"(half_offsets), "r"(half_values_masked)
+ : "r1", "q0", "m0", "q0", "v0", "v1", "memory");
sync_scatter(vtcm.vscatter16);
}
-/* scatter the 32 bit elements using intrinsics */
+/* scatter the 32 bit elements using HVX */
void vector_scatter_32(void)
{
- /* copy the offsets and values to vectors */
- HVX_Vector offsetslo = *(HVX_Vector *)word_offsets;
- HVX_Vector offsetshi = *(HVX_Vector *)&word_offsets[MATRIX_SIZE / 2];
- HVX_Vector valueslo = *(HVX_Vector *)word_values;
- HVX_Vector valueshi = *(HVX_Vector *)&word_values[MATRIX_SIZE / 2];
-
- VSCATTER_32(&vtcm.vscatter32, region_len, offsetslo, valueslo);
- VSCATTER_32(&vtcm.vscatter32, region_len, offsetshi, valueshi);
+ HVX_Vector *offsetslo = (HVX_Vector *)word_offsets;
+ HVX_Vector *offsetshi = (HVX_Vector *)&word_offsets[MATRIX_SIZE / 2];
+ HVX_Vector *valueslo = (HVX_Vector *)word_values;
+ HVX_Vector *valueshi = (HVX_Vector *)&word_values[MATRIX_SIZE / 2];
+
+ asm ("m0 = %1\n\t"
+ "v0 = vmem(%2 + #0)\n\t"
+ "v1 = vmem(%3 + #0)\n\t"
+ "vscatter(%0, m0, v0.w).w = v1\n\t"
+ : : "r"(vtcm.vscatter32), "r"(region_len),
+ "r"(offsetslo), "r"(valueslo)
+ : "m0", "v0", "v1", "memory");
+ asm ("m0 = %1\n\t"
+ "v0 = vmem(%2 + #0)\n\t"
+ "v1 = vmem(%3 + #0)\n\t"
+ "vscatter(%0, m0, v0.w).w = v1\n\t"
+ : : "r"(vtcm.vscatter32), "r"(region_len),
+ "r"(offsetshi), "r"(valueshi)
+ : "m0", "v0", "v1", "memory");
sync_scatter(vtcm.vscatter32);
}
-/* scatter-acc the 32 bit elements using intrinsics */
+/* scatter-accumulate the 32 bit elements using HVX */
void vector_scatter_32_acc(void)
{
- /* copy the offsets and values to vectors */
- HVX_Vector offsetslo = *(HVX_Vector *)word_offsets;
- HVX_Vector offsetshi = *(HVX_Vector *)&word_offsets[MATRIX_SIZE / 2];
- HVX_Vector valueslo = *(HVX_Vector *)word_values_acc;
- HVX_Vector valueshi = *(HVX_Vector *)&word_values_acc[MATRIX_SIZE / 2];
-
- VSCATTER_32_ACC(&vtcm.vscatter32, region_len, offsetslo, valueslo);
- VSCATTER_32_ACC(&vtcm.vscatter32, region_len, offsetshi, valueshi);
+ HVX_Vector *offsetslo = (HVX_Vector *)word_offsets;
+ HVX_Vector *offsetshi = (HVX_Vector *)&word_offsets[MATRIX_SIZE / 2];
+ HVX_Vector *valueslo = (HVX_Vector *)word_values_acc;
+ HVX_Vector *valueshi = (HVX_Vector *)&word_values_acc[MATRIX_SIZE / 2];
+
+ asm ("m0 = %1\n\t"
+ "v0 = vmem(%2 + #0)\n\t"
+ "v1 = vmem(%3 + #0)\n\t"
+ "vscatter(%0, m0, v0.w).w += v1\n\t"
+ : : "r"(vtcm.vscatter32), "r"(region_len),
+ "r"(offsetslo), "r"(valueslo)
+ : "m0", "v0", "v1", "memory");
+ asm ("m0 = %1\n\t"
+ "v0 = vmem(%2 + #0)\n\t"
+ "v1 = vmem(%3 + #0)\n\t"
+ "vscatter(%0, m0, v0.w).w += v1\n\t"
+ : : "r"(vtcm.vscatter32), "r"(region_len),
+ "r"(offsetshi), "r"(valueshi)
+ : "m0", "v0", "v1", "memory");
sync_scatter(vtcm.vscatter32);
}
-/* scatter the 32 bit elements using intrinsics */
+/* masked scatter the 32 bit elements using HVX */
void vector_scatter_32_masked(void)
{
- /* copy the offsets and values to vectors */
- HVX_Vector offsetslo = *(HVX_Vector *)word_offsets;
- HVX_Vector offsetshi = *(HVX_Vector *)&word_offsets[MATRIX_SIZE / 2];
- HVX_Vector valueslo = *(HVX_Vector *)word_values_masked;
- HVX_Vector valueshi = *(HVX_Vector *)&word_values_masked[MATRIX_SIZE / 2];
- HVX_Vector pred_reglo = *(HVX_Vector *)word_predicates;
- HVX_Vector pred_reghi = *(HVX_Vector *)&word_predicates[MATRIX_SIZE / 2];
- HVX_VectorPred predslo = VAND_VAL(pred_reglo, ~0);
- HVX_VectorPred predshi = VAND_VAL(pred_reghi, ~0);
-
- VSCATTER_32_MASKED(predslo, &vtcm.vscatter32, region_len, offsetslo,
- valueslo);
- VSCATTER_32_MASKED(predshi, &vtcm.vscatter32, region_len, offsetshi,
- valueshi);
+ HVX_Vector *offsetslo = (HVX_Vector *)word_offsets;
+ HVX_Vector *offsetshi = (HVX_Vector *)&word_offsets[MATRIX_SIZE / 2];
+ HVX_Vector *valueslo = (HVX_Vector *)word_values_masked;
+ HVX_Vector *valueshi = (HVX_Vector *)&word_values_masked[MATRIX_SIZE / 2];
+ HVX_Vector *predslo = (HVX_Vector *)word_predicates;
+ HVX_Vector *predshi = (HVX_Vector *)&word_predicates[MATRIX_SIZE / 2];
+
+ asm ("r1 = #-1\n\t"
+ "v0 = vmem(%0 + #0)\n\t"
+ "q0 = vand(v0, r1)\n\t"
+ "m0 = %2\n\t"
+ "v0 = vmem(%3 + #0)\n\t"
+ "v1 = vmem(%4 + #0)\n\t"
+ "if (q0) vscatter(%1, m0, v0.w).w = v1\n\t"
+ : : "r"(predslo), "r"(vtcm.vscatter32), "r"(region_len),
+ "r"(offsetslo), "r"(valueslo)
+ : "r1", "q0", "m0", "q0", "v0", "v1", "memory");
+ asm ("r1 = #-1\n\t"
+ "v0 = vmem(%0 + #0)\n\t"
+ "q0 = vand(v0, r1)\n\t"
+ "m0 = %2\n\t"
+ "v0 = vmem(%3 + #0)\n\t"
+ "v1 = vmem(%4 + #0)\n\t"
+ "if (q0) vscatter(%1, m0, v0.w).w = v1\n\t"
+ : : "r"(predshi), "r"(vtcm.vscatter32), "r"(region_len),
+ "r"(offsetshi), "r"(valueshi)
+ : "r1", "q0", "m0", "q0", "v0", "v1", "memory");
- sync_scatter(vtcm.vscatter16);
+ sync_scatter(vtcm.vscatter32);
}
-/* scatter the 16 bit elements with 32 bit offsets using intrinsics */
+/* scatter the 16 bit elements with 32 bit offsets using HVX */
void vector_scatter_16_32(void)
{
- HVX_VectorPair offsets;
- HVX_Vector values;
-
- /* get the word offsets in a vector pair */
- offsets = *(HVX_VectorPair *)word_offsets;
-
- /* these values need to be shuffled for the scatter */
- values = *(HVX_Vector *)half_values;
- values = VSHUFF_H(values);
-
- VSCATTER_16_32(&vtcm.vscatter16_32, region_len, offsets, values);
+ asm ("m0 = %1\n\t"
+ "v0 = vmem(%2 + #0)\n\t"
+ "v1 = vmem(%2 + #1)\n\t"
+ "v2 = vmem(%3 + #0)\n\t"
+ "v2.h = vshuff(v2.h)\n\t" /* shuffle the values for the scatter */
+ "vscatter(%0, m0, v1:0.w).h = v2\n\t"
+ : : "r"(vtcm.vscatter16_32), "r"(region_len),
+ "r"(word_offsets), "r"(half_values)
+ : "m0", "v0", "v1", "v2", "memory");
sync_scatter(vtcm.vscatter16_32);
}
-/* scatter-acc the 16 bit elements with 32 bit offsets using intrinsics */
+/* scatter-accumulate the 16 bit elements with 32 bit offsets using HVX */
void vector_scatter_16_32_acc(void)
{
- HVX_VectorPair offsets;
- HVX_Vector values;
-
- /* get the word offsets in a vector pair */
- offsets = *(HVX_VectorPair *)word_offsets;
-
- /* these values need to be shuffled for the scatter */
- values = *(HVX_Vector *)half_values_acc;
- values = VSHUFF_H(values);
-
- VSCATTER_16_32_ACC(&vtcm.vscatter16_32, region_len, offsets, values);
+ asm ("m0 = %1\n\t"
+ "v0 = vmem(%2 + #0)\n\t"
+ "v1 = vmem(%2 + #1)\n\t"
+ "v2 = vmem(%3 + #0)\n\t" \
+ "v2.h = vshuff(v2.h)\n\t" /* shuffle the values for the scatter */
+ "vscatter(%0, m0, v1:0.w).h += v2\n\t"
+ : : "r"(vtcm.vscatter16_32), "r"(region_len),
+ "r"(word_offsets), "r"(half_values_acc)
+ : "m0", "v0", "v1", "v2", "memory");
sync_scatter(vtcm.vscatter16_32);
}
-/* masked scatter the 16 bit elements with 32 bit offsets using intrinsics */
+/* masked scatter the 16 bit elements with 32 bit offsets using HVX */
void vector_scatter_16_32_masked(void)
{
- HVX_VectorPair offsets;
- HVX_Vector values;
- HVX_Vector pred_reg;
-
- /* get the word offsets in a vector pair */
- offsets = *(HVX_VectorPair *)word_offsets;
-
- /* these values need to be shuffled for the scatter */
- values = *(HVX_Vector *)half_values_masked;
- values = VSHUFF_H(values);
-
- pred_reg = *(HVX_Vector *)half_predicates;
- pred_reg = VSHUFF_H(pred_reg);
- HVX_VectorPred preds = VAND_VAL(pred_reg, ~0);
-
- VSCATTER_16_32_MASKED(preds, &vtcm.vscatter16_32, region_len, offsets,
- values);
+ asm ("r1 = #-1\n\t"
+ "v0 = vmem(%0 + #0)\n\t"
+ "v0.h = vshuff(v0.h)\n\t" /* shuffle the predicates */
+ "q0 = vand(v0, r1)\n\t"
+ "m0 = %2\n\t"
+ "v0 = vmem(%3 + #0)\n\t"
+ "v1 = vmem(%3 + #1)\n\t"
+ "v2 = vmem(%4 + #0)\n\t" \
+ "v2.h = vshuff(v2.h)\n\t" /* shuffle the values for the scatter */
+ "if (q0) vscatter(%1, m0, v1:0.w).h = v2\n\t"
+ : : "r"(half_predicates), "r"(vtcm.vscatter16_32), "r"(region_len),
+ "r"(word_offsets), "r"(half_values_masked)
+ : "r1", "q0", "m0", "v0", "v1", "v2", "memory");
sync_scatter(vtcm.vscatter16_32);
}
-/* gather the elements from the scatter16 buffer */
+/* gather the elements from the scatter16 buffer using HVX */
void vector_gather_16(void)
{
- HVX_Vector *vgather = (HVX_Vector *)&vtcm.vgather16;
- HVX_Vector offsets = *(HVX_Vector *)half_offsets;
-
- VGATHER_16(vgather, &vtcm.vscatter16, region_len, offsets);
-
- sync_gather(vgather);
+ asm ("m0 = %1\n\t"
+ "v0 = vmem(%2 + #0)\n\t"
+ "{ vtmp.h = vgather(%0, m0, v0.h).h\n\t"
+ " vmem(%3 + #0) = vtmp.new }\n\t"
+ : : "r"(vtcm.vscatter16), "r"(region_len),
+ "r"(half_offsets), "r"(vtcm.vgather16)
+ : "m0", "v0", "memory");
+
+ sync_gather(vtcm.vgather16);
}
static unsigned short gather_16_masked_init(void)
@@ -427,31 +423,51 @@ static unsigned short gather_16_masked_init(void)
return letter | (letter << 8);
}
+/* masked gather the elements from the scatter16 buffer using HVX */
void vector_gather_16_masked(void)
{
- HVX_Vector *vgather = (HVX_Vector *)&vtcm.vgather16;
- HVX_Vector offsets = *(HVX_Vector *)half_offsets;
- HVX_Vector pred_reg = *(HVX_Vector *)half_predicates;
- HVX_VectorPred preds = VAND_VAL(pred_reg, ~0);
-
- *vgather = VSPLAT_H(gather_16_masked_init());
- VGATHER_16_MASKED(vgather, preds, &vtcm.vscatter16, region_len, offsets);
-
- sync_gather(vgather);
+ unsigned short init = gather_16_masked_init();
+
+ asm ("v0.h = vsplat(%5)\n\t"
+ "vmem(%4 + #0) = v0\n\t" /* initialize the write area */
+ "r1 = #-1\n\t"
+ "v0 = vmem(%0 + #0)\n\t"
+ "q0 = vand(v0, r1)\n\t"
+ "m0 = %2\n\t"
+ "v0 = vmem(%3 + #0)\n\t"
+ "{ if (q0) vtmp.h = vgather(%1, m0, v0.h).h\n\t"
+ " vmem(%4 + #0) = vtmp.new }\n\t"
+ : : "r"(half_predicates), "r"(vtcm.vscatter16), "r"(region_len),
+ "r"(half_offsets), "r"(vtcm.vgather16), "r"(init)
+ : "r1", "q0", "m0", "v0", "memory");
+
+ sync_gather(vtcm.vgather16);
}
-/* gather the elements from the scatter32 buffer */
+/* gather the elements from the scatter32 buffer using HVX */
void vector_gather_32(void)
{
- HVX_Vector *vgatherlo = (HVX_Vector *)&vtcm.vgather32;
- HVX_Vector *vgatherhi =
- (HVX_Vector *)((int)&vtcm.vgather32 + (MATRIX_SIZE * 2));
- HVX_Vector offsetslo = *(HVX_Vector *)word_offsets;
- HVX_Vector offsetshi = *(HVX_Vector *)&word_offsets[MATRIX_SIZE / 2];
-
- VGATHER_32(vgatherlo, &vtcm.vscatter32, region_len, offsetslo);
- VGATHER_32(vgatherhi, &vtcm.vscatter32, region_len, offsetshi);
+ HVX_Vector *vgatherlo = (HVX_Vector *)vtcm.vgather32;
+ HVX_Vector *vgatherhi = (HVX_Vector *)&vtcm.vgather32[MATRIX_SIZE / 2];
+ HVX_Vector *offsetslo = (HVX_Vector *)word_offsets;
+ HVX_Vector *offsetshi = (HVX_Vector *)&word_offsets[MATRIX_SIZE / 2];
+
+ asm ("m0 = %1\n\t"
+ "v0 = vmem(%2 + #0)\n\t"
+ "{ vtmp.w = vgather(%0, m0, v0.w).w\n\t"
+ " vmem(%3 + #0) = vtmp.new }\n\t"
+ : : "r"(vtcm.vscatter32), "r"(region_len),
+ "r"(offsetslo), "r"(vgatherlo)
+ : "m0", "v0", "memory");
+ asm ("m0 = %1\n\t"
+ "v0 = vmem(%2 + #0)\n\t"
+ "{ vtmp.w = vgather(%0, m0, v0.w).w\n\t"
+ " vmem(%3 + #0) = vtmp.new }\n\t"
+ : : "r"(vtcm.vscatter32), "r"(region_len),
+ "r"(offsetshi), "r"(vgatherhi)
+ : "m0", "v0", "memory");
+ sync_gather(vgatherlo);
sync_gather(vgatherhi);
}
@@ -461,79 +477,88 @@ static unsigned int gather_32_masked_init(void)
return letter | (letter << 8) | (letter << 16) | (letter << 24);
}
+/* masked gather the elements from the scatter32 buffer using HVX */
void vector_gather_32_masked(void)
{
- HVX_Vector *vgatherlo = (HVX_Vector *)&vtcm.vgather32;
- HVX_Vector *vgatherhi =
- (HVX_Vector *)((int)&vtcm.vgather32 + (MATRIX_SIZE * 2));
- HVX_Vector offsetslo = *(HVX_Vector *)word_offsets;
- HVX_Vector offsetshi = *(HVX_Vector *)&word_offsets[MATRIX_SIZE / 2];
- HVX_Vector pred_reglo = *(HVX_Vector *)word_predicates;
- HVX_VectorPred predslo = VAND_VAL(pred_reglo, ~0);
- HVX_Vector pred_reghi = *(HVX_Vector *)&word_predicates[MATRIX_SIZE / 2];
- HVX_VectorPred predshi = VAND_VAL(pred_reghi, ~0);
-
- *vgatherlo = VSPLAT_H(gather_32_masked_init());
- *vgatherhi = VSPLAT_H(gather_32_masked_init());
- VGATHER_32_MASKED(vgatherlo, predslo, &vtcm.vscatter32, region_len,
- offsetslo);
- VGATHER_32_MASKED(vgatherhi, predshi, &vtcm.vscatter32, region_len,
- offsetshi);
+ unsigned int init = gather_32_masked_init();
+ HVX_Vector *vgatherlo = (HVX_Vector *)vtcm.vgather32;
+ HVX_Vector *vgatherhi = (HVX_Vector *)&vtcm.vgather32[MATRIX_SIZE / 2];
+ HVX_Vector *offsetslo = (HVX_Vector *)word_offsets;
+ HVX_Vector *offsetshi = (HVX_Vector *)&word_offsets[MATRIX_SIZE / 2];
+ HVX_Vector *predslo = (HVX_Vector *)word_predicates;
+ HVX_Vector *predshi = (HVX_Vector *)&word_predicates[MATRIX_SIZE / 2];
+
+ asm ("v0.h = vsplat(%5)\n\t"
+ "vmem(%4 + #0) = v0\n\t" /* initialize the write area */
+ "r1 = #-1\n\t"
+ "v0 = vmem(%0 + #0)\n\t"
+ "q0 = vand(v0, r1)\n\t"
+ "m0 = %2\n\t"
+ "v0 = vmem(%3 + #0)\n\t"
+ "{ if (q0) vtmp.w = vgather(%1, m0, v0.w).w\n\t"
+ " vmem(%4 + #0) = vtmp.new }\n\t"
+ : : "r"(predslo), "r"(vtcm.vscatter32), "r"(region_len),
+ "r"(offsetslo), "r"(vgatherlo), "r"(init)
+ : "r1", "q0", "m0", "v0", "memory");
+ asm ("v0.h = vsplat(%5)\n\t"
+ "vmem(%4 + #0) = v0\n\t" /* initialize the write area */
+ "r1 = #-1\n\t"
+ "v0 = vmem(%0 + #0)\n\t"
+ "q0 = vand(v0, r1)\n\t"
+ "m0 = %2\n\t"
+ "v0 = vmem(%3 + #0)\n\t"
+ "{ if (q0) vtmp.w = vgather(%1, m0, v0.w).w\n\t"
+ " vmem(%4 + #0) = vtmp.new }\n\t"
+ : : "r"(predshi), "r"(vtcm.vscatter32), "r"(region_len),
+ "r"(offsetshi), "r"(vgatherhi), "r"(init)
+ : "r1", "q0", "m0", "v0", "memory");
sync_gather(vgatherlo);
sync_gather(vgatherhi);
}
-/* gather the elements from the scatter16_32 buffer */
+/* gather the elements from the scatter16_32 buffer using HVX */
void vector_gather_16_32(void)
{
- HVX_Vector *vgather;
- HVX_VectorPair offsets;
- HVX_Vector values;
-
- /* get the vtcm address to gather from */
- vgather = (HVX_Vector *)&vtcm.vgather16_32;
-
- /* get the word offsets in a vector pair */
- offsets = *(HVX_VectorPair *)word_offsets;
-
- VGATHER_16_32(vgather, &vtcm.vscatter16_32, region_len, offsets);
-
- /* deal the elements to get the order back */
- values = *(HVX_Vector *)vgather;
- values = VDEAL_H(values);
-
- /* write it back to vtcm address */
- *(HVX_Vector *)vgather = values;
+ asm ("m0 = %1\n\t"
+ "v0 = vmem(%2 + #0)\n\t"
+ "v1 = vmem(%2 + #1)\n\t"
+ "{ vtmp.h = vgather(%0, m0, v1:0.w).h\n\t"
+ " vmem(%3 + #0) = vtmp.new }\n\t"
+ "v0 = vmem(%3 + #0)\n\t"
+ "v0.h = vdeal(v0.h)\n\t" /* deal the elements to get the order back */
+ "vmem(%3 + #0) = v0\n\t"
+ : : "r"(vtcm.vscatter16_32), "r"(region_len),
+ "r"(word_offsets), "r"(vtcm.vgather16_32)
+ : "m0", "v0", "v1", "memory");
+
+ sync_gather(vtcm.vgather16_32);
}
+/* masked gather the elements from the scatter16_32 buffer using HVX */
void vector_gather_16_32_masked(void)
{
- HVX_Vector *vgather;
- HVX_VectorPair offsets;
- HVX_Vector pred_reg;
- HVX_VectorPred preds;
- HVX_Vector values;
-
- /* get the vtcm address to gather from */
- vgather = (HVX_Vector *)&vtcm.vgather16_32;
-
- /* get the word offsets in a vector pair */
- offsets = *(HVX_VectorPair *)word_offsets;
- pred_reg = *(HVX_Vector *)half_predicates;
- pred_reg = VSHUFF_H(pred_reg);
- preds = VAND_VAL(pred_reg, ~0);
-
- *vgather = VSPLAT_H(gather_16_masked_init());
- VGATHER_16_32_MASKED(vgather, preds, &vtcm.vscatter16_32, region_len,
- offsets);
-
- /* deal the elements to get the order back */
- values = *(HVX_Vector *)vgather;
- values = VDEAL_H(values);
-
- /* write it back to vtcm address */
- *(HVX_Vector *)vgather = values;
+ unsigned short init = gather_16_masked_init();
+
+ asm ("v0.h = vsplat(%5)\n\t"
+ "vmem(%4 + #0) = v0\n\t" /* initialize the write area */
+ "r1 = #-1\n\t"
+ "v0 = vmem(%0 + #0)\n\t"
+ "v0.h = vshuff(v0.h)\n\t" /* shuffle the predicates */
+ "q0 = vand(v0, r1)\n\t"
+ "m0 = %2\n\t"
+ "v0 = vmem(%3 + #0)\n\t"
+ "v1 = vmem(%3 + #1)\n\t"
+ "{ if (q0) vtmp.h = vgather(%1, m0, v1:0.w).h\n\t"
+ " vmem(%4 + #0) = vtmp.new }\n\t"
+ "v0 = vmem(%4 + #0)\n\t"
+ "v0.h = vdeal(v0.h)\n\t" /* deal the elements to get the order back */
+ "vmem(%4 + #0) = v0\n\t"
+ : : "r"(half_predicates), "r"(vtcm.vscatter16_32), "r"(region_len),
+ "r"(word_offsets), "r"(vtcm.vgather16_32), "r"(init)
+ : "r1", "q0", "m0", "v0", "v1", "memory");
+
+ sync_gather(vtcm.vgather16_32);
}
static void check_buffer(const char *name, void *c, void *r, size_t size)
@@ -579,6 +604,7 @@ void scalar_scatter_16_acc(unsigned short *vscatter16)
}
}
+/* scatter-accumulate the 16 bit elements using C */
void check_scatter_16_acc()
{
memset(vscatter16_ref, FILL_CHAR,
@@ -589,7 +615,7 @@ void check_scatter_16_acc()
SCATTER_BUFFER_SIZE * sizeof(unsigned short));
}
-/* scatter the 16 bit elements using C */
+/* masked scatter the 16 bit elements using C */
void scalar_scatter_16_masked(unsigned short *vscatter16)
{
for (int i = 0; i < MATRIX_SIZE; i++) {
@@ -628,7 +654,7 @@ void check_scatter_32()
SCATTER_BUFFER_SIZE * sizeof(unsigned int));
}
-/* scatter the 32 bit elements using C */
+/* scatter-accumulate the 32 bit elements using C */
void scalar_scatter_32_acc(unsigned int *vscatter32)
{
for (int i = 0; i < MATRIX_SIZE; ++i) {
@@ -646,7 +672,7 @@ void check_scatter_32_acc()
SCATTER_BUFFER_SIZE * sizeof(unsigned int));
}
-/* scatter the 32 bit elements using C */
+/* masked scatter the 32 bit elements using C */
void scalar_scatter_32_masked(unsigned int *vscatter32)
{
for (int i = 0; i < MATRIX_SIZE; i++) {
@@ -667,7 +693,7 @@ void check_scatter_32_masked()
SCATTER_BUFFER_SIZE * sizeof(unsigned int));
}
-/* scatter the 32 bit elements using C */
+/* scatter the 16 bit elements with 32 bit offsets using C */
void scalar_scatter_16_32(unsigned short *vscatter16_32)
{
for (int i = 0; i < MATRIX_SIZE; ++i) {
@@ -684,7 +710,7 @@ void check_scatter_16_32()
SCATTER_BUFFER_SIZE * sizeof(unsigned short));
}
-/* scatter the 32 bit elements using C */
+/* scatter-accumulate the 16 bit elements with 32 bit offsets using C */
void scalar_scatter_16_32_acc(unsigned short *vscatter16_32)
{
for (int i = 0; i < MATRIX_SIZE; ++i) {
@@ -702,6 +728,7 @@ void check_scatter_16_32_acc()
SCATTER_BUFFER_SIZE * sizeof(unsigned short));
}
+/* masked scatter the 16 bit elements with 32 bit offsets using C */
void scalar_scatter_16_32_masked(unsigned short *vscatter16_32)
{
for (int i = 0; i < MATRIX_SIZE; i++) {
@@ -738,6 +765,7 @@ void check_gather_16()
MATRIX_SIZE * sizeof(unsigned short));
}
+/* masked gather the elements from the scatter buffer using C */
void scalar_gather_16_masked(unsigned short *vgather16)
{
for (int i = 0; i < MATRIX_SIZE; ++i) {
@@ -756,7 +784,7 @@ void check_gather_16_masked()
MATRIX_SIZE * sizeof(unsigned short));
}
-/* gather the elements from the scatter buffer using C */
+/* gather the elements from the scatter32 buffer using C */
void scalar_gather_32(unsigned int *vgather32)
{
for (int i = 0; i < MATRIX_SIZE; ++i) {
@@ -772,6 +800,7 @@ void check_gather_32(void)
MATRIX_SIZE * sizeof(unsigned int));
}
+/* masked gather the elements from the scatter32 buffer using C */
void scalar_gather_32_masked(unsigned int *vgather32)
{
for (int i = 0; i < MATRIX_SIZE; ++i) {
@@ -781,7 +810,6 @@ void scalar_gather_32_masked(unsigned int *vgather32)
}
}
-
void check_gather_32_masked(void)
{
memset(vgather32_ref, gather_32_masked_init(),
@@ -791,7 +819,7 @@ void check_gather_32_masked(void)
vgather32_ref, MATRIX_SIZE * sizeof(unsigned int));
}
-/* gather the elements from the scatter buffer using C */
+/* gather the elements from the scatter16_32 buffer using C */
void scalar_gather_16_32(unsigned short *vgather16_32)
{
for (int i = 0; i < MATRIX_SIZE; ++i) {
@@ -807,6 +835,7 @@ void check_gather_16_32(void)
MATRIX_SIZE * sizeof(unsigned short));
}
+/* masked gather the elements from the scatter16_32 buffer using C */
void scalar_gather_16_32_masked(unsigned short *vgather16_32)
{
for (int i = 0; i < MATRIX_SIZE; ++i) {