aboutsummaryrefslogtreecommitdiff
path: root/tests
diff options
context:
space:
mode:
authorRichard Henderson <richard.henderson@linaro.org>2023-06-06 12:11:34 -0700
committerRichard Henderson <richard.henderson@linaro.org>2023-06-06 12:11:34 -0700
commitf5e6786de4815751b0a3d2235c760361f228ea48 (patch)
tree544d0ff2d361be94e83bc620ea0e57b2886487ac /tests
parentc0dde5fc5ccce56b69095bc29af72987efd65d1e (diff)
parentf9ac778898cb28307e0f91421aba34d43c34b679 (diff)
Merge tag 'pull-target-arm-20230606' of https://git.linaro.org/people/pmaydell/qemu-arm into staging
target-arm queue: * Support gdbstub (guest debug) in HVF * xnlx-versal: Support CANFD controller * bpim2u: New board model: Banana Pi BPI-M2 Ultra * Emulate FEAT_LSE2 * allow DC CVA[D]P in user mode emulation * trap DCC access in user mode emulation # -----BEGIN PGP SIGNATURE----- # # iQJNBAABCAA3FiEE4aXFk81BneKOgxXPPCUl7RQ2DN4FAmR/AKUZHHBldGVyLm1h # eWRlbGxAbGluYXJvLm9yZwAKCRA8JSXtFDYM3jzIEACNepQGY44yPhrEG+wD4WAB # fH670KI33HcsFd2rGsC369gcssQbRIW/29reOzNhRMuol+kHI6OFaONpuKSdO0Rz # TLVIsnT2Uq8KwbYfLtDQt5knj027amPy75d4re8wIK1eZB4dOIHysqAvQrJYeync # 9obKku8xXGLwZh/mYHoVgHcZU0cPJO9nri39n1tV3JUBsgmqEURjzbZrMcF+yMX7 # bUzOYQvC1Iedmo+aWfx43u82AlNQFz1lsqmnQj7Z5rvv0HT+BRF5WzVMP0qRh5+Z # njkqmBH9xb9kkgeHmeMvHpWox+J+obeSmVg/4gDNlJpThmpuU0Vr7EXUN3MBQlV9 # lhyy6zrTwC/BToiQqdT2dnpao9FzXy5exfnqi/py5IuqfjAzSO+p61LlPPZ4cJri # pCK4yq2gzQXYfrlZkUJipvRMH8Xa4IdQx+w7lXrQoJdduF4/+6aJW/GAWSu0e7eC # zgBwaJjI7ENce8ixJnuEFUxUnaBo8dl72a0PGA1UU8PL+cJNOIpyhPk4goWQprdn # iFF4ZnjhBRZ2gk/4HGD9u5Vo2lNqP93YS5QhkGkF+HJsBmcOZgidIUpfHhPQvvHO # Np196T2cAETCWGV1xG4CaTpxN2ndRReq3C0/mzfhIbwhXEACtvAiSlO4KB8t6pJj # MzinCABXHcovJbGbxZ9j6w== # =8SdN # -----END PGP SIGNATURE----- # gpg: Signature made Tue 06 Jun 2023 02:47:17 AM PDT # gpg: using RSA key E1A5C593CD419DE28E8315CF3C2525ED14360CDE # gpg: issuer "peter.maydell@linaro.org" # gpg: Good signature from "Peter Maydell <peter.maydell@linaro.org>" [full] # gpg: aka "Peter Maydell <pmaydell@gmail.com>" [full] # gpg: aka "Peter Maydell <pmaydell@chiark.greenend.org.uk>" [full] # gpg: aka "Peter Maydell <peter@archaic.org.uk>" [unknown] * tag 'pull-target-arm-20230606' of https://git.linaro.org/people/pmaydell/qemu-arm: (42 commits) target/arm: trap DCC access in user mode emulation tests/tcg/aarch64: add DC CVA[D]P tests target/arm: allow DC CVA[D]P in user mode emulation target/arm: Enable FEAT_LSE2 for -cpu max tests/tcg/multiarch: Adjust sigbus.c tests/tcg/aarch64: Use stz2g in mte-7.c target/arm: Move mte check for store-exclusive target/arm: Relax ordered/atomic alignment checks for LSE2 target/arm: Add SCTLR.nAA to TBFLAG_A64 target/arm: Check alignment in helper_mte_check target/arm: Pass single_memop to gen_mte_checkN target/arm: Pass memop to gen_mte_check1* target/arm: Hoist finalize_memop out of do_fp_{ld, st} target/arm: Hoist finalize_memop out of do_gpr_{ld, st} target/arm: Load/store integer pair with one tcg operation target/arm: Sink gen_mte_check1 into load/store_exclusive target/arm: Use tcg_gen_qemu_{ld, st}_i128 in gen_sve_{ld, st}r target/arm: Use tcg_gen_qemu_st_i128 for STZG, STZ2G target/arm: Use tcg_gen_qemu_{st, ld}_i128 for do_fp_{st, ld} target/arm: Use tcg_gen_qemu_ld_i128 for LDXP ... Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
Diffstat (limited to 'tests')
-rw-r--r--tests/avocado/boot_linux_console.py176
-rw-r--r--tests/qtest/meson.build1
-rw-r--r--tests/qtest/xlnx-canfd-test.c423
-rw-r--r--tests/tcg/aarch64/Makefile.target11
-rw-r--r--tests/tcg/aarch64/dcpodp.c63
-rw-r--r--tests/tcg/aarch64/dcpop.c63
-rw-r--r--tests/tcg/aarch64/mte-7.c3
-rw-r--r--tests/tcg/multiarch/sigbus.c13
8 files changed, 747 insertions, 6 deletions
diff --git a/tests/avocado/boot_linux_console.py b/tests/avocado/boot_linux_console.py
index c0675809e6..6ed660611f 100644
--- a/tests/avocado/boot_linux_console.py
+++ b/tests/avocado/boot_linux_console.py
@@ -769,6 +769,182 @@ class BootLinuxConsole(LinuxKernelTest):
self.wait_for_console_pattern(
'Give root password for system maintenance')
+ def test_arm_bpim2u(self):
+ """
+ :avocado: tags=arch:arm
+ :avocado: tags=machine:bpim2u
+ :avocado: tags=accel:tcg
+ """
+ deb_url = ('https://apt.armbian.com/pool/main/l/linux-5.10.16-sunxi/'
+ 'linux-image-current-sunxi_21.02.2_armhf.deb')
+ deb_hash = '9fa84beda245cabf0b4fa84cf6eaa7738ead1da0'
+ deb_path = self.fetch_asset(deb_url, asset_hash=deb_hash)
+ kernel_path = self.extract_from_deb(deb_path,
+ '/boot/vmlinuz-5.10.16-sunxi')
+ dtb_path = ('/usr/lib/linux-image-current-sunxi/'
+ 'sun8i-r40-bananapi-m2-ultra.dtb')
+ dtb_path = self.extract_from_deb(deb_path, dtb_path)
+
+ self.vm.set_console()
+ kernel_command_line = (self.KERNEL_COMMON_COMMAND_LINE +
+ 'console=ttyS0,115200n8 '
+ 'earlycon=uart,mmio32,0x1c28000')
+ self.vm.add_args('-kernel', kernel_path,
+ '-dtb', dtb_path,
+ '-append', kernel_command_line)
+ self.vm.launch()
+ console_pattern = 'Kernel command line: %s' % kernel_command_line
+ self.wait_for_console_pattern(console_pattern)
+
+ def test_arm_bpim2u_initrd(self):
+ """
+ :avocado: tags=arch:arm
+ :avocado: tags=accel:tcg
+ :avocado: tags=machine:bpim2u
+ """
+ deb_url = ('https://apt.armbian.com/pool/main/l/linux-5.10.16-sunxi/'
+ 'linux-image-current-sunxi_21.02.2_armhf.deb')
+ deb_hash = '9fa84beda245cabf0b4fa84cf6eaa7738ead1da0'
+ deb_path = self.fetch_asset(deb_url, asset_hash=deb_hash)
+ kernel_path = self.extract_from_deb(deb_path,
+ '/boot/vmlinuz-5.10.16-sunxi')
+ dtb_path = ('/usr/lib/linux-image-current-sunxi/'
+ 'sun8i-r40-bananapi-m2-ultra.dtb')
+ dtb_path = self.extract_from_deb(deb_path, dtb_path)
+ initrd_url = ('https://github.com/groeck/linux-build-test/raw/'
+ '2eb0a73b5d5a28df3170c546ddaaa9757e1e0848/rootfs/'
+ 'arm/rootfs-armv7a.cpio.gz')
+ initrd_hash = '604b2e45cdf35045846b8bbfbf2129b1891bdc9c'
+ initrd_path_gz = self.fetch_asset(initrd_url, asset_hash=initrd_hash)
+ initrd_path = os.path.join(self.workdir, 'rootfs.cpio')
+ archive.gzip_uncompress(initrd_path_gz, initrd_path)
+
+ self.vm.set_console()
+ kernel_command_line = (self.KERNEL_COMMON_COMMAND_LINE +
+ 'console=ttyS0,115200 '
+ 'panic=-1 noreboot')
+ self.vm.add_args('-kernel', kernel_path,
+ '-dtb', dtb_path,
+ '-initrd', initrd_path,
+ '-append', kernel_command_line,
+ '-no-reboot')
+ self.vm.launch()
+ self.wait_for_console_pattern('Boot successful.')
+
+ exec_command_and_wait_for_pattern(self, 'cat /proc/cpuinfo',
+ 'Allwinner sun8i Family')
+ exec_command_and_wait_for_pattern(self, 'cat /proc/iomem',
+ 'system-control@1c00000')
+ exec_command_and_wait_for_pattern(self, 'reboot',
+ 'reboot: Restarting system')
+ # Wait for VM to shut down gracefully
+ self.vm.wait()
+
+ def test_arm_bpim2u_gmac(self):
+ """
+ :avocado: tags=arch:arm
+ :avocado: tags=accel:tcg
+ :avocado: tags=machine:bpim2u
+ :avocado: tags=device:sd
+ """
+ self.require_netdev('user')
+
+ deb_url = ('https://apt.armbian.com/pool/main/l/linux-5.10.16-sunxi/'
+ 'linux-image-current-sunxi_21.02.2_armhf.deb')
+ deb_hash = '9fa84beda245cabf0b4fa84cf6eaa7738ead1da0'
+ deb_path = self.fetch_asset(deb_url, asset_hash=deb_hash)
+ kernel_path = self.extract_from_deb(deb_path,
+ '/boot/vmlinuz-5.10.16-sunxi')
+ dtb_path = ('/usr/lib/linux-image-current-sunxi/'
+ 'sun8i-r40-bananapi-m2-ultra.dtb')
+ dtb_path = self.extract_from_deb(deb_path, dtb_path)
+ rootfs_url = ('http://storage.kernelci.org/images/rootfs/buildroot/'
+ 'buildroot-baseline/20221116.0/armel/rootfs.ext2.xz')
+ rootfs_hash = 'fae32f337c7b87547b10f42599acf109da8b6d9a'
+ rootfs_path_xz = self.fetch_asset(rootfs_url, asset_hash=rootfs_hash)
+ rootfs_path = os.path.join(self.workdir, 'rootfs.cpio')
+ archive.lzma_uncompress(rootfs_path_xz, rootfs_path)
+ image_pow2ceil_expand(rootfs_path)
+
+ self.vm.set_console()
+ kernel_command_line = (self.KERNEL_COMMON_COMMAND_LINE +
+ 'console=ttyS0,115200 '
+ 'root=/dev/mmcblk0 rootwait rw '
+ 'panic=-1 noreboot')
+ self.vm.add_args('-kernel', kernel_path,
+ '-dtb', dtb_path,
+ '-drive', 'file=' + rootfs_path + ',if=sd,format=raw',
+ '-net', 'nic,model=gmac,netdev=host_gmac',
+ '-netdev', 'user,id=host_gmac',
+ '-append', kernel_command_line,
+ '-no-reboot')
+ self.vm.launch()
+ shell_ready = "/bin/sh: can't access tty; job control turned off"
+ self.wait_for_console_pattern(shell_ready)
+
+ exec_command_and_wait_for_pattern(self, 'cat /proc/cpuinfo',
+ 'Allwinner sun8i Family')
+ exec_command_and_wait_for_pattern(self, 'cat /proc/partitions',
+ 'mmcblk0')
+ exec_command_and_wait_for_pattern(self, 'ifconfig eth0 up',
+ 'eth0: Link is Up')
+ exec_command_and_wait_for_pattern(self, 'udhcpc eth0',
+ 'udhcpc: lease of 10.0.2.15 obtained')
+ exec_command_and_wait_for_pattern(self, 'ping -c 3 10.0.2.2',
+ '3 packets transmitted, 3 packets received, 0% packet loss')
+ exec_command_and_wait_for_pattern(self, 'reboot',
+ 'reboot: Restarting system')
+ # Wait for VM to shut down gracefully
+ self.vm.wait()
+
+ @skipUnless(os.getenv('AVOCADO_ALLOW_LARGE_STORAGE'), 'storage limited')
+ def test_arm_bpim2u_openwrt_22_03_3(self):
+ """
+ :avocado: tags=arch:arm
+ :avocado: tags=machine:bpim2u
+ :avocado: tags=device:sd
+ """
+
+ # This test download a 8.9 MiB compressed image and expand it
+ # to 127 MiB.
+ image_url = ('https://downloads.openwrt.org/releases/22.03.3/targets/'
+ 'sunxi/cortexa7/openwrt-22.03.3-sunxi-cortexa7-'
+ 'sinovoip_bananapi-m2-ultra-ext4-sdcard.img.gz')
+ image_hash = ('5b41b4e11423e562c6011640f9a7cd3b'
+ 'dd0a3d42b83430f7caa70a432e6cd82c')
+ image_path_gz = self.fetch_asset(image_url, asset_hash=image_hash,
+ algorithm='sha256')
+ image_path = archive.extract(image_path_gz, self.workdir)
+ image_pow2ceil_expand(image_path)
+
+ self.vm.set_console()
+ self.vm.add_args('-drive', 'file=' + image_path + ',if=sd,format=raw',
+ '-nic', 'user',
+ '-no-reboot')
+ self.vm.launch()
+
+ kernel_command_line = (self.KERNEL_COMMON_COMMAND_LINE +
+ 'usbcore.nousb '
+ 'noreboot')
+
+ self.wait_for_console_pattern('U-Boot SPL')
+
+ interrupt_interactive_console_until_pattern(
+ self, 'Hit any key to stop autoboot:', '=>')
+ exec_command_and_wait_for_pattern(self, "setenv extraargs '" +
+ kernel_command_line + "'", '=>')
+ exec_command_and_wait_for_pattern(self, 'boot', 'Starting kernel ...');
+
+ self.wait_for_console_pattern(
+ 'Please press Enter to activate this console.')
+
+ exec_command_and_wait_for_pattern(self, ' ', 'root@')
+
+ exec_command_and_wait_for_pattern(self, 'cat /proc/cpuinfo',
+ 'Allwinner sun8i Family')
+ exec_command_and_wait_for_pattern(self, 'cat /proc/iomem',
+ 'system-control@1c00000')
+
def test_arm_orangepi(self):
"""
:avocado: tags=arch:arm
diff --git a/tests/qtest/meson.build b/tests/qtest/meson.build
index 1d8a53a669..5fa6833ad7 100644
--- a/tests/qtest/meson.build
+++ b/tests/qtest/meson.build
@@ -216,6 +216,7 @@ qtests_aarch64 = \
(config_all.has_key('CONFIG_TCG') and config_all_devices.has_key('CONFIG_TPM_TIS_SYSBUS') ? \
['tpm-tis-device-test', 'tpm-tis-device-swtpm-test'] : []) + \
(config_all_devices.has_key('CONFIG_XLNX_ZYNQMP_ARM') ? ['xlnx-can-test', 'fuzz-xlnx-dp-test'] : []) + \
+ (config_all_devices.has_key('CONFIG_XLNX_VERSAL') ? ['xlnx-canfd-test'] : []) + \
(config_all_devices.has_key('CONFIG_RASPI') ? ['bcm2835-dma-test'] : []) + \
(config_all.has_key('CONFIG_TCG') and \
config_all_devices.has_key('CONFIG_TPM_TIS_I2C') ? ['tpm-tis-i2c-test'] : []) + \
diff --git a/tests/qtest/xlnx-canfd-test.c b/tests/qtest/xlnx-canfd-test.c
new file mode 100644
index 0000000000..76ee106d4f
--- /dev/null
+++ b/tests/qtest/xlnx-canfd-test.c
@@ -0,0 +1,423 @@
+/*
+ * SPDX-License-Identifier: MIT
+ *
+ * QTests for the Xilinx Versal CANFD controller.
+ *
+ * Copyright (c) 2022 AMD Inc.
+ *
+ * Written-by: Vikram Garhwal<vikram.garhwal@amd.com>
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+#include "qemu/osdep.h"
+#include "libqtest.h"
+
+/* Base address. */
+#define CANFD0_BASE_ADDR 0xff060000
+#define CANFD1_BASE_ADDR 0xff070000
+
+/* Register addresses. */
+#define R_SRR_OFFSET 0x00
+#define R_MSR_OFFSET 0x04
+#define R_FILTER_CONTROL_REGISTER 0xe0
+#define R_SR_OFFSET 0x18
+#define R_ISR_OFFSET 0x1c
+#define R_IER_OFFSET 0x20
+#define R_ICR_OFFSET 0x24
+#define R_TX_READY_REQ_REGISTER 0x90
+#define RX_FIFO_STATUS_REGISTER 0xe8
+#define R_TXID_OFFSET 0x100
+#define R_TXDLC_OFFSET 0x104
+#define R_TXDATA1_OFFSET 0x108
+#define R_TXDATA2_OFFSET 0x10c
+#define R_AFMR_REGISTER0 0xa00
+#define R_AFIR_REGISTER0 0xa04
+#define R_RX0_ID_OFFSET 0x2100
+#define R_RX0_DLC_OFFSET 0x2104
+#define R_RX0_DATA1_OFFSET 0x2108
+#define R_RX0_DATA2_OFFSET 0x210c
+
+/* CANFD modes. */
+#define SRR_CONFIG_MODE 0x00
+#define MSR_NORMAL_MODE 0x00
+#define MSR_LOOPBACK_MODE (1 << 1)
+#define ENABLE_CANFD (1 << 1)
+
+/* CANFD status. */
+#define STATUS_CONFIG_MODE (1 << 0)
+#define STATUS_NORMAL_MODE (1 << 3)
+#define STATUS_LOOPBACK_MODE (1 << 1)
+#define ISR_TXOK (1 << 1)
+#define ISR_RXOK (1 << 4)
+
+#define ENABLE_ALL_FILTERS 0xffffffff
+#define ENABLE_ALL_INTERRUPTS 0xffffffff
+
+/* We are sending one canfd message. */
+#define TX_READY_REG_VAL 0x1
+
+#define FIRST_RX_STORE_INDEX 0x1
+#define STATUS_REG_MASK 0xf
+#define DLC_FD_BIT_SHIFT 0x1b
+#define DLC_FD_BIT_MASK 0xf8000000
+#define FIFO_STATUS_READ_INDEX_MASK 0x3f
+#define FIFO_STATUS_FILL_LEVEL_MASK 0x7f00
+#define FILL_LEVEL_SHIFT 0x8
+
+/* CANFD frame size ID, DLC and 16 DATA word. */
+#define CANFD_FRAME_SIZE 18
+/* CAN frame size ID, DLC and 2 DATA word. */
+#define CAN_FRAME_SIZE 4
+
+/* Set the filters for CANFD controller. */
+static void enable_filters(QTestState *qts)
+{
+ const uint32_t arr_afmr[32] = { 0xb423deaa, 0xa2a40bdc, 0x1b64f486,
+ 0x95c0d4ee, 0xe0c44528, 0x4b407904,
+ 0xd2673f46, 0x9fc638d6, 0x8844f3d8,
+ 0xa607d1e8, 0x67871bf4, 0xc2557dc,
+ 0x9ea5b53e, 0x3643c0cc, 0x5a05ea8e,
+ 0x83a46d84, 0x4a25c2b8, 0x93a66008,
+ 0x2e467470, 0xedc66118, 0x9086f9f2,
+ 0xfa23dd36, 0xb6654b90, 0xb221b8ca,
+ 0x3467d1e2, 0xa3a55542, 0x5b26a012,
+ 0x2281ea7e, 0xcea0ece8, 0xdc61e588,
+ 0x2e5676a, 0x16821320 };
+
+ const uint32_t arr_afir[32] = { 0xa833dfa1, 0x255a477e, 0x3a4bb1c5,
+ 0x8f560a6c, 0x27f38903, 0x2fecec4d,
+ 0xa014c66d, 0xec289b8, 0x7e52dead,
+ 0x82e94f3c, 0xcf3e3c5c, 0x66059871,
+ 0x3f213df4, 0x25ac3959, 0xa12e9bef,
+ 0xa3ad3af, 0xbafd7fe, 0xb3cb40fd,
+ 0x5d9caa81, 0x2ed61902, 0x7cd64a0,
+ 0x4b1fa538, 0x9b5ced8c, 0x150de059,
+ 0xd2794227, 0x635e820a, 0xbb6b02cf,
+ 0xbb58176, 0x570025bb, 0xa78d9658,
+ 0x49d735df, 0xe5399d2f };
+
+ /* Passing the respective array values to all the AFMR and AFIR pairs. */
+ for (int i = 0; i < 32; i++) {
+ /* For CANFD0. */
+ qtest_writel(qts, CANFD0_BASE_ADDR + R_AFMR_REGISTER0 + 8 * i,
+ arr_afmr[i]);
+ qtest_writel(qts, CANFD0_BASE_ADDR + R_AFIR_REGISTER0 + 8 * i,
+ arr_afir[i]);
+
+ /* For CANFD1. */
+ qtest_writel(qts, CANFD1_BASE_ADDR + R_AFMR_REGISTER0 + 8 * i,
+ arr_afmr[i]);
+ qtest_writel(qts, CANFD1_BASE_ADDR + R_AFIR_REGISTER0 + 8 * i,
+ arr_afir[i]);
+ }
+
+ /* Enable all the pairs from AFR register. */
+ qtest_writel(qts, CANFD0_BASE_ADDR + R_FILTER_CONTROL_REGISTER,
+ ENABLE_ALL_FILTERS);
+ qtest_writel(qts, CANFD1_BASE_ADDR + R_FILTER_CONTROL_REGISTER,
+ ENABLE_ALL_FILTERS);
+}
+
+static void configure_canfd(QTestState *qts, uint8_t mode)
+{
+ uint32_t status = 0;
+
+ /* Put CANFD0 and CANFD1 in config mode. */
+ qtest_writel(qts, CANFD0_BASE_ADDR + R_SRR_OFFSET, SRR_CONFIG_MODE);
+ qtest_writel(qts, CANFD1_BASE_ADDR + R_SRR_OFFSET, SRR_CONFIG_MODE);
+
+ /* Write mode of operation in Mode select register. */
+ qtest_writel(qts, CANFD0_BASE_ADDR + R_MSR_OFFSET, mode);
+ qtest_writel(qts, CANFD1_BASE_ADDR + R_MSR_OFFSET, mode);
+
+ enable_filters(qts);
+
+ /* Check here if CANFD0 and CANFD1 are in config mode. */
+ status = qtest_readl(qts, CANFD0_BASE_ADDR + R_SR_OFFSET);
+ status = status & STATUS_REG_MASK;
+ g_assert_cmpint(status, ==, STATUS_CONFIG_MODE);
+
+ status = qtest_readl(qts, CANFD1_BASE_ADDR + R_SR_OFFSET);
+ status = status & STATUS_REG_MASK;
+ g_assert_cmpint(status, ==, STATUS_CONFIG_MODE);
+
+ qtest_writel(qts, CANFD1_BASE_ADDR + R_IER_OFFSET, ENABLE_ALL_INTERRUPTS);
+ qtest_writel(qts, CANFD1_BASE_ADDR + R_IER_OFFSET, ENABLE_ALL_INTERRUPTS);
+
+ qtest_writel(qts, CANFD0_BASE_ADDR + R_SRR_OFFSET, ENABLE_CANFD);
+ qtest_writel(qts, CANFD1_BASE_ADDR + R_SRR_OFFSET, ENABLE_CANFD);
+}
+
+static void generate_random_data(uint32_t *buf_tx, bool is_canfd_frame)
+{
+ /* Generate random TX data for CANFD frame. */
+ if (is_canfd_frame) {
+ for (int i = 0; i < CANFD_FRAME_SIZE - 2; i++) {
+ buf_tx[2 + i] = rand();
+ }
+ } else {
+ /* Generate random TX data for CAN frame. */
+ for (int i = 0; i < CAN_FRAME_SIZE - 2; i++) {
+ buf_tx[2 + i] = rand();
+ }
+ }
+}
+
+static void read_data(QTestState *qts, uint64_t can_base_addr, uint32_t *buf_rx)
+{
+ uint32_t int_status;
+ uint32_t fifo_status_reg_value;
+ /* At which RX FIFO the received data is stored. */
+ uint8_t store_ind = 0;
+ bool is_canfd_frame = false;
+
+ /* Read the interrupt on CANFD rx. */
+ int_status = qtest_readl(qts, can_base_addr + R_ISR_OFFSET) & ISR_RXOK;
+
+ g_assert_cmpint(int_status, ==, ISR_RXOK);
+
+ /* Find the fill level and read index. */
+ fifo_status_reg_value = qtest_readl(qts, can_base_addr +
+ RX_FIFO_STATUS_REGISTER);
+
+ store_ind = (fifo_status_reg_value & FIFO_STATUS_READ_INDEX_MASK) +
+ ((fifo_status_reg_value & FIFO_STATUS_FILL_LEVEL_MASK) >>
+ FILL_LEVEL_SHIFT);
+
+ g_assert_cmpint(store_ind, ==, FIRST_RX_STORE_INDEX);
+
+ /* Read the RX register data for CANFD. */
+ buf_rx[0] = qtest_readl(qts, can_base_addr + R_RX0_ID_OFFSET);
+ buf_rx[1] = qtest_readl(qts, can_base_addr + R_RX0_DLC_OFFSET);
+
+ is_canfd_frame = (buf_rx[1] >> DLC_FD_BIT_SHIFT) & 1;
+
+ if (is_canfd_frame) {
+ for (int i = 0; i < CANFD_FRAME_SIZE - 2; i++) {
+ buf_rx[i + 2] = qtest_readl(qts,
+ can_base_addr + R_RX0_DATA1_OFFSET + 4 * i);
+ }
+ } else {
+ buf_rx[2] = qtest_readl(qts, can_base_addr + R_RX0_DATA1_OFFSET);
+ buf_rx[3] = qtest_readl(qts, can_base_addr + R_RX0_DATA2_OFFSET);
+ }
+
+ /* Clear the RX interrupt. */
+ qtest_writel(qts, CANFD1_BASE_ADDR + R_ICR_OFFSET, ISR_RXOK);
+}
+
+static void write_data(QTestState *qts, uint64_t can_base_addr,
+ const uint32_t *buf_tx, bool is_canfd_frame)
+{
+ /* Write the TX register data for CANFD. */
+ qtest_writel(qts, can_base_addr + R_TXID_OFFSET, buf_tx[0]);
+ qtest_writel(qts, can_base_addr + R_TXDLC_OFFSET, buf_tx[1]);
+
+ if (is_canfd_frame) {
+ for (int i = 0; i < CANFD_FRAME_SIZE - 2; i++) {
+ qtest_writel(qts, can_base_addr + R_TXDATA1_OFFSET + 4 * i,
+ buf_tx[2 + i]);
+ }
+ } else {
+ qtest_writel(qts, can_base_addr + R_TXDATA1_OFFSET, buf_tx[2]);
+ qtest_writel(qts, can_base_addr + R_TXDATA2_OFFSET, buf_tx[3]);
+ }
+}
+
+static void send_data(QTestState *qts, uint64_t can_base_addr)
+{
+ uint32_t int_status;
+
+ qtest_writel(qts, can_base_addr + R_TX_READY_REQ_REGISTER,
+ TX_READY_REG_VAL);
+
+ /* Read the interrupt on CANFD for tx. */
+ int_status = qtest_readl(qts, can_base_addr + R_ISR_OFFSET) & ISR_TXOK;
+
+ g_assert_cmpint(int_status, ==, ISR_TXOK);
+
+ /* Clear the interrupt for tx. */
+ qtest_writel(qts, CANFD0_BASE_ADDR + R_ICR_OFFSET, ISR_TXOK);
+}
+
+static void match_rx_tx_data(const uint32_t *buf_tx, const uint32_t *buf_rx,
+ bool is_canfd_frame)
+{
+ uint16_t size = 0;
+ uint8_t len = CAN_FRAME_SIZE;
+
+ if (is_canfd_frame) {
+ len = CANFD_FRAME_SIZE;
+ }
+
+ while (size < len) {
+ if (R_RX0_ID_OFFSET + 4 * size == R_RX0_DLC_OFFSET) {
+ g_assert_cmpint((buf_rx[size] & DLC_FD_BIT_MASK), ==,
+ (buf_tx[size] & DLC_FD_BIT_MASK));
+ } else {
+ if (!is_canfd_frame && size == 4) {
+ break;
+ }
+
+ g_assert_cmpint(buf_rx[size], ==, buf_tx[size]);
+ }
+
+ size++;
+ }
+}
+/*
+ * Xilinx CANFD supports both CAN and CANFD frames. This test will be
+ * transferring CAN frame i.e. 8 bytes of data from CANFD0 and CANFD1 through
+ * canbus. CANFD0 initiate the data transfer to can-bus, CANFD1 receives the
+ * data. Test compares the can frame data sent from CANFD0 and received on
+ * CANFD1.
+ */
+static void test_can_data_transfer(void)
+{
+ uint32_t buf_tx[CAN_FRAME_SIZE] = { 0x5a5bb9a4, 0x80000000,
+ 0x12345678, 0x87654321 };
+ uint32_t buf_rx[CAN_FRAME_SIZE] = { 0x00, 0x00, 0x00, 0x00 };
+ uint32_t status = 0;
+
+ generate_random_data(buf_tx, false);
+
+ QTestState *qts = qtest_init("-machine xlnx-versal-virt"
+ " -object can-bus,id=canbus"
+ " -machine canbus0=canbus"
+ " -machine canbus1=canbus"
+ );
+
+ configure_canfd(qts, MSR_NORMAL_MODE);
+
+ /* Check if CANFD0 and CANFD1 are in Normal mode. */
+ status = qtest_readl(qts, CANFD0_BASE_ADDR + R_SR_OFFSET);
+ status = status & STATUS_REG_MASK;
+ g_assert_cmpint(status, ==, STATUS_NORMAL_MODE);
+
+ status = qtest_readl(qts, CANFD1_BASE_ADDR + R_SR_OFFSET);
+ status = status & STATUS_REG_MASK;
+ g_assert_cmpint(status, ==, STATUS_NORMAL_MODE);
+
+ write_data(qts, CANFD0_BASE_ADDR, buf_tx, false);
+
+ send_data(qts, CANFD0_BASE_ADDR);
+ read_data(qts, CANFD1_BASE_ADDR, buf_rx);
+ match_rx_tx_data(buf_tx, buf_rx, false);
+
+ qtest_quit(qts);
+}
+
+/*
+ * This test will be transferring CANFD frame i.e. 64 bytes of data from CANFD0
+ * and CANFD1 through canbus. CANFD0 initiate the data transfer to can-bus,
+ * CANFD1 receives the data. Test compares the CANFD frame data sent from CANFD0
+ * with received on CANFD1.
+ */
+static void test_canfd_data_transfer(void)
+{
+ uint32_t buf_tx[CANFD_FRAME_SIZE] = { 0x5a5bb9a4, 0xf8000000 };
+ uint32_t buf_rx[CANFD_FRAME_SIZE] = { 0x00, 0x00, 0x00, 0x00 };
+ uint32_t status = 0;
+
+ generate_random_data(buf_tx, true);
+
+ QTestState *qts = qtest_init("-machine xlnx-versal-virt"
+ " -object can-bus,id=canbus"
+ " -machine canbus0=canbus"
+ " -machine canbus1=canbus"
+ );
+
+ configure_canfd(qts, MSR_NORMAL_MODE);
+
+ /* Check if CANFD0 and CANFD1 are in Normal mode. */
+ status = qtest_readl(qts, CANFD0_BASE_ADDR + R_SR_OFFSET);
+ status = status & STATUS_REG_MASK;
+ g_assert_cmpint(status, ==, STATUS_NORMAL_MODE);
+
+ status = qtest_readl(qts, CANFD1_BASE_ADDR + R_SR_OFFSET);
+ status = status & STATUS_REG_MASK;
+ g_assert_cmpint(status, ==, STATUS_NORMAL_MODE);
+
+ write_data(qts, CANFD0_BASE_ADDR, buf_tx, true);
+
+ send_data(qts, CANFD0_BASE_ADDR);
+ read_data(qts, CANFD1_BASE_ADDR, buf_rx);
+ match_rx_tx_data(buf_tx, buf_rx, true);
+
+ qtest_quit(qts);
+}
+
+/*
+ * This test is performing loopback mode on CANFD0 and CANFD1. Data sent from
+ * TX of each CANFD0 and CANFD1 are compared with RX register data for
+ * respective CANFD Controller.
+ */
+static void test_can_loopback(void)
+{
+ uint32_t buf_tx[CANFD_FRAME_SIZE] = { 0x5a5bb9a4, 0xf8000000 };
+ uint32_t buf_rx[CANFD_FRAME_SIZE] = { 0x00, 0x00, 0x00, 0x00 };
+ uint32_t status = 0;
+
+ generate_random_data(buf_tx, true);
+
+ QTestState *qts = qtest_init("-machine xlnx-versal-virt"
+ " -object can-bus,id=canbus"
+ " -machine canbus0=canbus"
+ " -machine canbus1=canbus"
+ );
+
+ configure_canfd(qts, MSR_LOOPBACK_MODE);
+
+ /* Check if CANFD0 and CANFD1 are set in correct loopback mode. */
+ status = qtest_readl(qts, CANFD0_BASE_ADDR + R_SR_OFFSET);
+ status = status & STATUS_REG_MASK;
+ g_assert_cmpint(status, ==, STATUS_LOOPBACK_MODE);
+
+ status = qtest_readl(qts, CANFD1_BASE_ADDR + R_SR_OFFSET);
+ status = status & STATUS_REG_MASK;
+ g_assert_cmpint(status, ==, STATUS_LOOPBACK_MODE);
+
+ write_data(qts, CANFD0_BASE_ADDR, buf_tx, true);
+
+ send_data(qts, CANFD0_BASE_ADDR);
+ read_data(qts, CANFD0_BASE_ADDR, buf_rx);
+ match_rx_tx_data(buf_tx, buf_rx, true);
+
+ generate_random_data(buf_tx, true);
+
+ write_data(qts, CANFD1_BASE_ADDR, buf_tx, true);
+
+ send_data(qts, CANFD1_BASE_ADDR);
+ read_data(qts, CANFD1_BASE_ADDR, buf_rx);
+ match_rx_tx_data(buf_tx, buf_rx, true);
+
+ qtest_quit(qts);
+}
+
+int main(int argc, char **argv)
+{
+ g_test_init(&argc, &argv, NULL);
+
+ qtest_add_func("/net/canfd/can_data_transfer", test_can_data_transfer);
+ qtest_add_func("/net/canfd/canfd_data_transfer", test_canfd_data_transfer);
+ qtest_add_func("/net/canfd/can_loopback", test_can_loopback);
+
+ return g_test_run();
+}
diff --git a/tests/tcg/aarch64/Makefile.target b/tests/tcg/aarch64/Makefile.target
index 0315795487..3430fd3cd8 100644
--- a/tests/tcg/aarch64/Makefile.target
+++ b/tests/tcg/aarch64/Makefile.target
@@ -21,12 +21,23 @@ config-cc.mak: Makefile
$(quiet-@)( \
$(call cc-option,-march=armv8.1-a+sve, CROSS_CC_HAS_SVE); \
$(call cc-option,-march=armv8.1-a+sve2, CROSS_CC_HAS_SVE2); \
+ $(call cc-option,-march=armv8.2-a, CROSS_CC_HAS_ARMV8_2); \
$(call cc-option,-march=armv8.3-a, CROSS_CC_HAS_ARMV8_3); \
+ $(call cc-option,-march=armv8.5-a, CROSS_CC_HAS_ARMV8_5); \
$(call cc-option,-mbranch-protection=standard, CROSS_CC_HAS_ARMV8_BTI); \
$(call cc-option,-march=armv8.5-a+memtag, CROSS_CC_HAS_ARMV8_MTE); \
$(call cc-option,-march=armv9-a+sme, CROSS_CC_HAS_ARMV9_SME)) 3> config-cc.mak
-include config-cc.mak
+ifneq ($(CROSS_CC_HAS_ARMV8_2),)
+AARCH64_TESTS += dcpop
+dcpop: CFLAGS += -march=armv8.2-a
+endif
+ifneq ($(CROSS_CC_HAS_ARMV8_5),)
+AARCH64_TESTS += dcpodp
+dcpodp: CFLAGS += -march=armv8.5-a
+endif
+
# Pauth Tests
ifneq ($(CROSS_CC_HAS_ARMV8_3),)
AARCH64_TESTS += pauth-1 pauth-2 pauth-4 pauth-5
diff --git a/tests/tcg/aarch64/dcpodp.c b/tests/tcg/aarch64/dcpodp.c
new file mode 100644
index 0000000000..2cf7df2e07
--- /dev/null
+++ b/tests/tcg/aarch64/dcpodp.c
@@ -0,0 +1,63 @@
+/*
+ * Test execution of DC CVADP instruction.
+ *
+ * Copyright (c) 2023 Zhuojia Shen <chaosdefinition@hotmail.com>
+ * SPDX-License-Identifier: GPL-2.0-or-later
+ */
+
+#include <asm/hwcap.h>
+#include <sys/auxv.h>
+
+#include <signal.h>
+#include <stdbool.h>
+#include <stdio.h>
+#include <stdlib.h>
+
+#ifndef HWCAP2_DCPODP
+#define HWCAP2_DCPODP (1 << 0)
+#endif
+
+bool should_fail = false;
+
+static void signal_handler(int sig, siginfo_t *si, void *data)
+{
+ ucontext_t *uc = (ucontext_t *)data;
+
+ if (should_fail) {
+ uc->uc_mcontext.pc += 4;
+ } else {
+ exit(EXIT_FAILURE);
+ }
+}
+
+static int do_dc_cvadp(void)
+{
+ struct sigaction sa = {
+ .sa_flags = SA_SIGINFO,
+ .sa_sigaction = signal_handler,
+ };
+
+ sigemptyset(&sa.sa_mask);
+ if (sigaction(SIGSEGV, &sa, NULL) < 0) {
+ perror("sigaction");
+ return EXIT_FAILURE;
+ }
+
+ asm volatile("dc cvadp, %0\n\t" :: "r"(&sa));
+
+ should_fail = true;
+ asm volatile("dc cvadp, %0\n\t" :: "r"(NULL));
+ should_fail = false;
+
+ return EXIT_SUCCESS;
+}
+
+int main(void)
+{
+ if (getauxval(AT_HWCAP2) & HWCAP2_DCPODP) {
+ return do_dc_cvadp();
+ } else {
+ printf("SKIP: no HWCAP2_DCPODP on this system\n");
+ return EXIT_SUCCESS;
+ }
+}
diff --git a/tests/tcg/aarch64/dcpop.c b/tests/tcg/aarch64/dcpop.c
new file mode 100644
index 0000000000..a332a804a4
--- /dev/null
+++ b/tests/tcg/aarch64/dcpop.c
@@ -0,0 +1,63 @@
+/*
+ * Test execution of DC CVAP instruction.
+ *
+ * Copyright (c) 2023 Zhuojia Shen <chaosdefinition@hotmail.com>
+ * SPDX-License-Identifier: GPL-2.0-or-later
+ */
+
+#include <asm/hwcap.h>
+#include <sys/auxv.h>
+
+#include <signal.h>
+#include <stdbool.h>
+#include <stdio.h>
+#include <stdlib.h>
+
+#ifndef HWCAP_DCPOP
+#define HWCAP_DCPOP (1 << 16)
+#endif
+
+bool should_fail = false;
+
+static void signal_handler(int sig, siginfo_t *si, void *data)
+{
+ ucontext_t *uc = (ucontext_t *)data;
+
+ if (should_fail) {
+ uc->uc_mcontext.pc += 4;
+ } else {
+ exit(EXIT_FAILURE);
+ }
+}
+
+static int do_dc_cvap(void)
+{
+ struct sigaction sa = {
+ .sa_flags = SA_SIGINFO,
+ .sa_sigaction = signal_handler,
+ };
+
+ sigemptyset(&sa.sa_mask);
+ if (sigaction(SIGSEGV, &sa, NULL) < 0) {
+ perror("sigaction");
+ return EXIT_FAILURE;
+ }
+
+ asm volatile("dc cvap, %0\n\t" :: "r"(&sa));
+
+ should_fail = true;
+ asm volatile("dc cvap, %0\n\t" :: "r"(NULL));
+ should_fail = false;
+
+ return EXIT_SUCCESS;
+}
+
+int main(void)
+{
+ if (getauxval(AT_HWCAP) & HWCAP_DCPOP) {
+ return do_dc_cvap();
+ } else {
+ printf("SKIP: no HWCAP_DCPOP on this system\n");
+ return EXIT_SUCCESS;
+ }
+}
diff --git a/tests/tcg/aarch64/mte-7.c b/tests/tcg/aarch64/mte-7.c
index a981de62d4..04974f9ebb 100644
--- a/tests/tcg/aarch64/mte-7.c
+++ b/tests/tcg/aarch64/mte-7.c
@@ -19,8 +19,7 @@ int main(int ac, char **av)
p = (void *)((unsigned long)p | (1ul << 56));
/* Store tag in sequential granules. */
- asm("stg %0, [%0]" : : "r"(p + 0x0ff0));
- asm("stg %0, [%0]" : : "r"(p + 0x1000));
+ asm("stz2g %0, [%0]" : : "r"(p + 0x0ff0));
/*
* Perform an unaligned store with tag 1 crossing the pages.
diff --git a/tests/tcg/multiarch/sigbus.c b/tests/tcg/multiarch/sigbus.c
index 8134c5fd56..f47c7390e7 100644
--- a/tests/tcg/multiarch/sigbus.c
+++ b/tests/tcg/multiarch/sigbus.c
@@ -6,8 +6,13 @@
#include <endian.h>
-unsigned long long x = 0x8877665544332211ull;
-void * volatile p = (void *)&x + 1;
+char x[32] __attribute__((aligned(16))) = {
+ 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08,
+ 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10,
+ 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18,
+ 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, 0x20,
+};
+void * volatile p = (void *)&x + 15;
void sigbus(int sig, siginfo_t *info, void *uc)
{
@@ -60,9 +65,9 @@ int main()
* We might as well validate the unaligned load worked.
*/
if (BYTE_ORDER == LITTLE_ENDIAN) {
- assert(tmp == 0x55443322);
+ assert(tmp == 0x13121110);
} else {
- assert(tmp == 0x77665544);
+ assert(tmp == 0x10111213);
}
return EXIT_SUCCESS;
}