From nobody Mon May 15 15:42:24 2023 X-Original-To: dev-commits-src-all@mlmmj.nyi.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2610:1c1:1:606c::19:1]) by mlmmj.nyi.freebsd.org (Postfix) with ESMTP id 4QKkC45qsNz4BlQb; Mon, 15 May 2023 15:42:24 +0000 (UTC) (envelope-from git@FreeBSD.org) Received: from mxrelay.nyi.freebsd.org (mxrelay.nyi.freebsd.org [IPv6:2610:1c1:1:606c::19:3]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256 client-signature RSA-PSS (4096 bits) client-digest SHA256) (Client CN "mxrelay.nyi.freebsd.org", Issuer "R3" (verified OK)) by mx1.freebsd.org (Postfix) with ESMTPS id 4QKkC45dZPz3GkT; Mon, 15 May 2023 15:42:24 +0000 (UTC) (envelope-from git@FreeBSD.org) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=freebsd.org; s=dkim; t=1684165344; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding; bh=pm0338ytfb1N+bAj/epc+Sh6e1oyhfaj4K/bHJRw/oE=; b=ueT3qoidGAMDj//rFBEvsRcWI0upC7/FTlk8w6DlTqc5/fbKdwnmXPcVk7UMPLKJf7jilR aDcaQJrW1JVj+HRjuLlAHOcrAIZYftunOgajdnyrr/DMvmBL8EEdJhDpMeDndtjh7KofSs QXvW2k8Rq4f9Hu/nRmJIoGpijPkSQWA+pbnrcNL/SVAkWuEMWqHZIPdDW3b+Q1RwDj/tQQ jetERIwsMBv8nLvt4jgnqPRxJ3VGihP1beQA7ywXwKJuncOPlAJo4oDoxEbUegW1mHBhk2 IEokCT+bQuDkk3KP+kzQYfdTIri3uGUIv8+ptWEDXua0QRkhLow5QbMAfzvaLg== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=freebsd.org; s=dkim; t=1684165344; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding; bh=pm0338ytfb1N+bAj/epc+Sh6e1oyhfaj4K/bHJRw/oE=; b=yZlI415Mfq/Wz6Zx5nLyMJ77BtLK7uj6PXendgeLePN65uZ65G71eeXQyjfSmlhJ622afB cmp/5Bfjzh7pnO6LWVC81rYAjMltyq4VAJDnO7RmR9rXLnnLuOnHAO0K5zKczoaS68OIfd hsJmwD7uxoYFGf6BcTXKwIVziIP8pvd8VxOYLQcyJAJIsbbuH6PmZOAOyfkwEwuW65T5r3 WtS0CXLL1zugGm+P094T6Cxd4vPvmAaA/TAGwf6u43fMUl2vh2TAUHJcttPi0ovNqof/1W hTRqshAjoT3JPS0Lqr07xFc8jA7wkni7CgVjswvcdUBJogpFfaW3N/9UC9ff/A== ARC-Authentication-Results: i=1; mx1.freebsd.org; none ARC-Seal: i=1; s=dkim; d=freebsd.org; t=1684165344; a=rsa-sha256; cv=none; b=DFYcVlqisi2bEJE0JS2hBqb8ALAItSriqwETU4V6dhkKOnQF0/t8gnI1RRobepFIla02vE 6I6jb84ULCOULRRL10GjKIfuQ5TUDSQrND2Mro32UxE6lHf6T5VQzEHa8GijKLlrNf58U0 DLvcLza9o3oRD3eJ0vgk89XwP70C47FvOj9ONMsXZIWujZflEU9RKCj6idHDhF6k2KLQB3 BXHH6SGiDSZ1KGHRIYJtKAmnLJ3wb2MNCgQuzsD9Vm+mokH5SkaS2ZjAhx8WHxKzupUmSa 916TGvXVuEo0jb0kb9qmAL8R7Rkce/oZucgP35npkGf6UbBhPfD5kzKN5BzzAQ== Received: from gitrepo.freebsd.org (gitrepo.freebsd.org [IPv6:2610:1c1:1:6068::e6a:5]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256) (Client did not present a certificate) by mxrelay.nyi.freebsd.org (Postfix) with ESMTPS id 4QKkC442VYzlVF; Mon, 15 May 2023 15:42:24 +0000 (UTC) (envelope-from git@FreeBSD.org) Received: from gitrepo.freebsd.org ([127.0.1.44]) by gitrepo.freebsd.org (8.16.1/8.16.1) with ESMTP id 34FFgOZW071781; Mon, 15 May 2023 15:42:24 GMT (envelope-from git@gitrepo.freebsd.org) Received: (from git@localhost) by gitrepo.freebsd.org (8.16.1/8.16.1/Submit) id 34FFgONF071780; Mon, 15 May 2023 15:42:24 GMT (envelope-from git) Date: Mon, 15 May 2023 15:42:24 GMT Message-Id: <202305151542.34FFgONF071780@gitrepo.freebsd.org> To: src-committers@FreeBSD.org, dev-commits-src-all@FreeBSD.org, dev-commits-src-main@FreeBSD.org From: Kyle Evans Subject: git: ccb59683b983 - main - arm64: add tests for swp/swpb emulation List-Id: Commit messages for all branches of the src repository List-Archive: https://lists.freebsd.org/archives/dev-commits-src-all List-Help: List-Post: List-Subscribe: List-Unsubscribe: Sender: owner-dev-commits-src-all@freebsd.org X-BeenThere: dev-commits-src-all@freebsd.org MIME-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: 8bit X-Git-Committer: kevans X-Git-Repository: src X-Git-Refname: refs/heads/main X-Git-Reftype: branch X-Git-Commit: ccb59683b98360afaf5b5bb641a68fea22c68d0b Auto-Submitted: auto-generated X-ThisMailContainsUnwantedMimeParts: N The branch main has been updated by kevans: URL: https://cgit.FreeBSD.org/src/commit/?id=ccb59683b98360afaf5b5bb641a68fea22c68d0b commit ccb59683b98360afaf5b5bb641a68fea22c68d0b Author: Kyle Evans AuthorDate: 2023-05-15 15:42:16 +0000 Commit: Kyle Evans CommitDate: 2023-05-15 15:42:16 +0000 arm64: add tests for swp/swpb emulation One test is suitable to be hooked up to the build, so I've done this here. The other test lives in tools/regression because failure is a bit more subjective -- generally, one runs it for some unbounded amount of time and observe if it eventually exits because two threads acquired the same mutex. Reviewed by: imp, mmel Sponsored by: Stormshield Sponsored by: Klara, Inc. Differential Revision: https://reviews.freebsd.org/D39668 --- etc/mtree/BSD.tests.dist | 2 + tests/sys/Makefile | 1 + tests/sys/compat32/Makefile | 6 + tests/sys/compat32/Makefile.inc | 4 + tests/sys/compat32/aarch64/Makefile | 24 ++ tests/sys/compat32/aarch64/common.sh | 9 + tests/sys/compat32/aarch64/swp_cond_test.sh | 14 + tests/sys/compat32/aarch64/swp_cond_test_impl.S | 413 ++++++++++++++++++++++ tests/sys/compat32/aarch64/swp_test.sh | 14 + tests/sys/compat32/aarch64/swp_test_impl.S | 216 +++++++++++ tools/regression/compat32/aarch64/Makefile | 4 + tools/regression/compat32/aarch64/swp_test_impl.S | 410 +++++++++++++++++++++ 12 files changed, 1117 insertions(+) diff --git a/etc/mtree/BSD.tests.dist b/etc/mtree/BSD.tests.dist index 5d99653100df..77c07960f938 100644 --- a/etc/mtree/BSD.tests.dist +++ b/etc/mtree/BSD.tests.dist @@ -750,6 +750,8 @@ .. .. .. + compat32 + .. devrandom .. dtrace diff --git a/tests/sys/Makefile b/tests/sys/Makefile index 8f83445f9d91..3e9a30105a1d 100644 --- a/tests/sys/Makefile +++ b/tests/sys/Makefile @@ -10,6 +10,7 @@ TESTS_SUBDIRS+= ${_audit} TESTS_SUBDIRS+= auditpipe TESTS_SUBDIRS+= capsicum TESTS_SUBDIRS+= ${_cddl} +TESTS_SUBDIRS+= compat32 TESTS_SUBDIRS+= devrandom TESTS_SUBDIRS+= fifo TESTS_SUBDIRS+= file diff --git a/tests/sys/compat32/Makefile b/tests/sys/compat32/Makefile new file mode 100644 index 000000000000..31834de16246 --- /dev/null +++ b/tests/sys/compat32/Makefile @@ -0,0 +1,6 @@ + +.if exists(${.CURDIR}/${MACHINE_ARCH}) +SUBDIR+= ${MACHINE_ARCH} +.endif + +.include diff --git a/tests/sys/compat32/Makefile.inc b/tests/sys/compat32/Makefile.inc new file mode 100644 index 000000000000..0220ac0431e9 --- /dev/null +++ b/tests/sys/compat32/Makefile.inc @@ -0,0 +1,4 @@ + +TESTSDIR= ${TESTSBASE}/sys/compat32 + +.include "../Makefile.inc" diff --git a/tests/sys/compat32/aarch64/Makefile b/tests/sys/compat32/aarch64/Makefile new file mode 100644 index 000000000000..716182b15d9c --- /dev/null +++ b/tests/sys/compat32/aarch64/Makefile @@ -0,0 +1,24 @@ +PACKAGE= tests +FILESGROUPS+= asmprogs + +ACFLAGS= -target armv7-unknown-freebsd${OS_REVISION} -nostdlib -Wl,-e -Wl,main -static + +TAP_TESTS_SH+= swp_cond_test +TAP_TESTS_SH+= swp_test +${PACKAGE}FILES+= common.sh + +# Each test will individually respect the compat.arm.emul_swp +# sysctl upon entry. +TEST_METADATA.swp_cond_test+= is_exclusive=true +TEST_METADATA.swp_test+= is_exclusive=true + +asmprogsMODE= 0755 +asmprogs+= swp_cond_test_impl swp_test_impl +asmprogsDIR= ${TESTSDIR} + +.for aprog in ${asmprogs} +${aprog}: ${aprog}.S + ${CC} ${ACFLAGS} -o ${.TARGET} ${.ALLSRC} +.endfor + +.include diff --git a/tests/sys/compat32/aarch64/common.sh b/tests/sys/compat32/aarch64/common.sh new file mode 100644 index 000000000000..f8b02e8ac157 --- /dev/null +++ b/tests/sys/compat32/aarch64/common.sh @@ -0,0 +1,9 @@ +#!/bin/sh + +if ! sysctl -n kern.features.compat_freebsd_32bit >/dev/null 2>&1; then + echo "1..0 # Skipped: Kernel not built with COMPAT_FREEBSD32" + exit 0 +elif ! sysctl -n kern.supported_archs | grep -q '\'; then + echo "1..0 # Skipped: 32-bit ARM not supported on this hardware" + exit 0 +fi diff --git a/tests/sys/compat32/aarch64/swp_cond_test.sh b/tests/sys/compat32/aarch64/swp_cond_test.sh new file mode 100644 index 000000000000..8edfa43b3e7e --- /dev/null +++ b/tests/sys/compat32/aarch64/swp_cond_test.sh @@ -0,0 +1,14 @@ +#!/bin/sh + +scriptdir=$(dirname $(realpath "$0")) + +. ${scriptdir}/common.sh + +# Ensure emul_swp is enabled just for this test; we'll turn it back off if +# it wasn't enabled before the test. +emul_swpval=$(sysctl -n compat.arm.emul_swp) +sysctl compat.arm.emul_swp=1 >/dev/null +${scriptdir}/swp_test_impl +if [ "$emul_swpval" -ne 1 ]; then + sysctl compat.arm.emul_swp="$emul_swpval" >/dev/null +fi diff --git a/tests/sys/compat32/aarch64/swp_cond_test_impl.S b/tests/sys/compat32/aarch64/swp_cond_test_impl.S new file mode 100644 index 000000000000..d29db44832b1 --- /dev/null +++ b/tests/sys/compat32/aarch64/swp_cond_test_impl.S @@ -0,0 +1,413 @@ +/* + * SPDX-License-Identifier: BSD-2-Clause + * + * Copyright (c) 2021 Warner Losh + * Copyright (c) 2023 Stormshield + * Copyright (c) 2023 Klara, Inc. + */ + +#include + +#define STDOUT_FILENO 1 +#define SWP_MAGIC 0xffc0 +#define SWPB_MAGIC 0xc0c0 + + .text + .file "swp_test.S" + .syntax unified + .globl main + .p2align 2 + .type main,%function + .code 32 + +main: + sub sp, #0x04 + /* r4 is our failed test counter */ + mov r4, #0 + /* r6 is our current teset counter */ + mov r6, #1 + + movw r0, :lower16:.L.testheader + movt r0, :upper16:.L.testheader + ldr r1, =(.L.testheaderEnd - .L.testheader - 1) + bl print + + /* eq */ + bl reset + mov r1, #SWP_MAGIC + cmp r1, r1 + swpeq r0, r1, [r0] + bl expect_success + + /* Returned 0 (bad) or 1 (ok) */ + cmp r0, #0 + beq 1f + + /* !eq */ + bl reset + mov r1, #SWP_MAGIC + mov r2, #0 + cmp r1, r2 + swpeq r0, r1, [r0] + bl expect_fail + + /* Don't care about the return of the second one, just print */ +1: + movw r0, :lower16:.L.eq + movt r0, :upper16:.L.eq + ldr r1, =(.L.eqEnd - .L.eq - 1) + bl print_result + add r6, r6, #1 /* Next test */ + + /* cs */ + bl reset + mov r1, #SWP_MAGIC + movw r3, #0xffff + movt r3, #0xffff + /* Overflow */ + adds r2, r3, r3 + swpcs r0, r1, [r0] + bl expect_success + + /* Returned 0 (bad) or 1 (ok) */ + cmp r0, #0 + beq 2f + + /* !cs */ + bl reset + mov r1, #SWP_MAGIC + mov r3, #0x00 + adds r2, r3, #0x08 + swpcs r0, r1, [r0] + bl expect_fail + + /* Don't care about the return of the second one, just print */ +2: + movw r0, :lower16:.L.cs + movt r0, :upper16:.L.cs + ldr r1, =(.L.csEnd - .L.cs - 1) + bl print_result + add r6, r6, #1 /* Next test */ + + /* mi */ + bl reset + mov r1, #SWP_MAGIC + mov r2, #0 + /* Underflow */ + subs r2, r2, #0x05 + swpmi r0, r1, [r0] + bl expect_success + + /* Returned 0 (bad) or 1 (ok) */ + cmp r0, #0 + beq 3f + + /* !mi */ + bl reset + mov r1, #SWP_MAGIC + mov r2, #0x10 + subs r2, r2, #0x08 + swpmi r0, r1, [r0] + bl expect_fail + + /* Don't care about the return of the second one, just print */ +3: + movw r0, :lower16:.L.mi + movt r0, :upper16:.L.mi + ldr r1, =(.L.miEnd - .L.mi - 1) + bl print_result + add r6, r6, #1 /* Next test */ + + /* vs */ + bl reset + mov r1, #SWP_MAGIC + movw r3, #0xffff + movt r3, #0x7fff + /* Overflow */ + adds r2, r3, #0x10 + swpvs r0, r1, [r0] + bl expect_success + + /* Returned 0 (bad) or 1 (ok) */ + cmp r0, #0 + beq 4f + + /* !vs */ + bl reset + mov r1, #SWP_MAGIC + mov r3, #0x00 + adds r2, r3, #0x08 + swpvs r0, r1, [r0] + bl expect_fail + + /* Don't care about the return of the second one, just print */ +4: + movw r0, :lower16:.L.vs + movt r0, :upper16:.L.vs + ldr r1, =(.L.vsEnd - .L.vs - 1) + bl print_result + add r6, r6, #1 /* Next test */ + + /* hi */ + bl reset + mov r1, #SWP_MAGIC + mov r2, #0x00 + mov r3, #0x01 + cmp r3, r2 + swphi r0, r1, [r0] + bl expect_success + + /* Returned 0 (bad) or 1 (ok) */ + cmp r0, #0 + beq 5f + + /* !hi */ + bl reset + mov r1, #SWP_MAGIC + mov r2, #0x00 + mov r3, #0x01 + cmp r2, r3 + swphi r0, r1, [r0] + bl expect_fail + + /* Don't care about the return of the second one, just print */ +5: + movw r0, :lower16:.L.hi + movt r0, :upper16:.L.hi + ldr r1, =(.L.hiEnd - .L.hi - 1) + bl print_result + add r6, r6, #1 /* Next test */ + + /* ge */ + bl reset + mov r1, #SWP_MAGIC + mov r2, #0x01 + cmp r2, r2 + swpge r0, r1, [r0] + bl expect_success + + /* Returned 0 (bad) or 1 (ok) */ + cmp r0, #0 + beq 6f + + /* !ge */ + bl reset + mov r1, #SWP_MAGIC + mov r2, #0x00 + mov r3, #0x01 + cmp r2, r3 + swpge r0, r1, [r0] + bl expect_fail + + /* Don't care about the return of the second one, just print */ +6: + movw r0, :lower16:.L.ge + movt r0, :upper16:.L.ge + ldr r1, =(.L.geEnd - .L.ge - 1) + bl print_result + add r6, r6, #1 /* Next test */ + + /* gt */ + bl reset + mov r1, #SWP_MAGIC + mov r2, #0x00 + mov r3, #0x01 + cmp r3, r2 + swpgt r0, r1, [r0] + bl expect_success + + /* Returned 0 (bad) or 1 (ok) */ + cmp r0, #0 + beq 7f + + /* !ge */ + bl reset + mov r1, #SWP_MAGIC + mov r2, #0x00 + mov r3, #0x01 + cmp r2, r3 + swpgt r0, r1, [r0] + bl expect_fail + + /* Don't care about the return of the second one, just print */ +7: + movw r0, :lower16:.L.gt + movt r0, :upper16:.L.gt + ldr r1, =(.L.gtEnd - .L.gt - 1) + bl print_result + add r6, r6, #1 /* Next test */ + + mov r0, r4 /* retval */ + ldr r7, =SYS_exit + swi 0 + + .p2align 2 + .type print_result,%function + .code 32 +print_result: + push {r4, r5, lr} + /* Save the label, size for our result */ + mov r4, r0 + mov r5, r1 + + movw r0, :lower16:.L.ok + movt r0, :upper16:.L.ok + ldr r1, =(.L.okEnd - .L.ok - 1) + bl print + mov r0, r6 + add r0, #0x30 /* "0" + test number */ + mov r1, #0x01 + str r0, [sp] + mov r0, sp + bl print + movw r0, :lower16:.L.swp + movt r0, :upper16:.L.swp + ldr r1, =(.L.swpEnd - .L.swp - 1) + bl print + mov r0, r4 + mov r1, r5 + bl print + movw r0, :lower16:.L.term + movt r0, :upper16:.L.term + ldr r1, =(.L.termEnd - .L.term - 1) + bl print + + pop {r4, r5, lr} + bx lr + + .p2align 2 + .type reset,%function + .code 32 +reset: + /* Reset sp[0] and return the address used */ + mov r0, #0x03 + str r0, [sp] + mov r0, sp + bx lr + + .p2align 2 + .type expect_fail,%function + .code 32 +expect_fail: + /* Just check the stack value */ + ldr r0, [sp] + mov r1, #0x03 + cmp r0, r1 + bne 1f + + /* Success (not swapped) */ + mov r0, #1 + bx lr + +1: + /* Fail (swapped) */ + /* Print the "not" part */ + movw r0, :lower16:.L.not + movt r0, :upper16:.L.not + ldr r1, =(.L.notEnd - .L.not - 1) + push {lr} + bl print + pop {lr} + + /* Failed */ + add r4, r4, #1 + mov r0, #0 + bx lr + + .p2align 2 + .type expect_success,%function + .code 32 +expect_success: + /* Old value should be 3 */ + cmp r0, #0x03 + beq 1f + b 3f + +1: + /* Check stack value */ + ldr r0, [sp] + mov r1, #SWP_MAGIC + cmp r0, r1 + beq 2f + b 3f + +2: + mov r0, #1 + bx lr + +3: + /* Print the "not" part */ + movw r0, :lower16:.L.not + movt r0, :upper16:.L.not + ldr r1, =(.L.notEnd - .L.not - 1) + push {lr} + bl print + pop {lr} + + /* Failed */ + add r4, r4, #1 + mov r0, #0 + bx lr + + .p2align 2 + .type print,%function + .code 32 +print: + /* r0 - string, r1 = size */ + mov r2, r1 + mov r1, r0 + ldr r0, =STDOUT_FILENO + ldr r7, =SYS_write + swi 0 + + bx lr + +.L.testheader: + .asciz "1..7\n" +.L.testheaderEnd: + .size .L.testheader, .L.testheaderEnd - .L.testheader + +.L.not: + .asciz "not " +.L.notEnd: + .size .L.not, .L.notEnd - .L.not +.L.ok: + .asciz "ok " +.L.okEnd: + .size .L.ok, .L.okEnd - .L.ok +.L.swp: + .asciz " - swp" +.L.swpEnd: + .size .L.swp, .L.swpEnd - .L.swp +.L.eq: + .asciz "eq" +.L.eqEnd: + .size .L.eq, .L.eqEnd - .L.eq +.L.cs: + .asciz "cs" +.L.csEnd: + .size .L.cs, .L.csEnd - .L.cs +.L.mi: + .asciz "mi" +.L.miEnd: + .size .L.mi, .L.miEnd - .L.mi +.L.vs: + .asciz "vs" +.L.vsEnd: + .size .L.vs, .L.vsEnd - .L.vs +.L.hi: + .asciz "hi" +.L.hiEnd: + .size .L.hi, .L.hiEnd - .L.hi +.L.ge: + .asciz "ge" +.L.geEnd: + .size .L.ge, .L.geEnd - .L.ge +.L.gt: + .asciz "gt" +.L.gtEnd: + .size .L.gt, .L.gtEnd - .L.gt +.L.term: + .asciz "\n" +.L.termEnd: + .size .L.term, .L.termEnd - .L.term diff --git a/tests/sys/compat32/aarch64/swp_test.sh b/tests/sys/compat32/aarch64/swp_test.sh new file mode 100644 index 000000000000..8edfa43b3e7e --- /dev/null +++ b/tests/sys/compat32/aarch64/swp_test.sh @@ -0,0 +1,14 @@ +#!/bin/sh + +scriptdir=$(dirname $(realpath "$0")) + +. ${scriptdir}/common.sh + +# Ensure emul_swp is enabled just for this test; we'll turn it back off if +# it wasn't enabled before the test. +emul_swpval=$(sysctl -n compat.arm.emul_swp) +sysctl compat.arm.emul_swp=1 >/dev/null +${scriptdir}/swp_test_impl +if [ "$emul_swpval" -ne 1 ]; then + sysctl compat.arm.emul_swp="$emul_swpval" >/dev/null +fi diff --git a/tests/sys/compat32/aarch64/swp_test_impl.S b/tests/sys/compat32/aarch64/swp_test_impl.S new file mode 100644 index 000000000000..0e8047f1a6cf --- /dev/null +++ b/tests/sys/compat32/aarch64/swp_test_impl.S @@ -0,0 +1,216 @@ +/* + * SPDX-License-Identifier: BSD-2-Clause + * + * Copyright (c) 2021 Warner Losh + * Copyright (c) 2023 Stormshield + * Copyright (c) 2023 Klara, Inc. + */ + +#include + +#define STDOUT_FILENO 1 +#define SWP_MAGIC 0xffc0 +#define SWPB_MAGIC 0xc0c0 + + .text + .file "swp_test.S" + .syntax unified + .globl main + .p2align 2 + .type main,%function + .code 32 + +main: + sub sp, #0x04 + /* r4 is our failed test counter */ + mov r4, #0 + + movw r0, :lower16:.L.testheader + movt r0, :upper16:.L.testheader + ldr r1, =(.L.testheaderEnd - .L.testheader - 1) + bl print + + /* Target address */ + mov r0, #0x03 + str r0, [sp] + mov r0, sp + + /* Load value */ + mov r1, #SWP_MAGIC + + /* swp it */ + swp r0, r1, [r0] + + /* Old value should be 3 */ + cmp r0, #0x03 + bne 1f + + /* Check stack value */ + ldr r0, [sp] + mov r1, #SWP_MAGIC + cmp r0, r1 + bne 1f + b 2f + +1: + /* Denote the failed test */ + add r4, #1 + /* "No" part of the notification */ + movw r0, :lower16:.L.boknot + movt r0, :upper16:.L.boknot + ldr r1, =(.L.boknotEnd - .L.boknot - 1) + bl print + +2: + /* Notify */ + movw r0, :lower16:.L.ok1 + movt r0, :upper16:.L.ok1 + ldr r1, =(.L.ok1End - .L.ok1 - 1) + bl print + + movw r5, #SWPB_MAGIC + movt r5, #SWPB_MAGIC + + /* Using r6 as our accumulator */ + mov r6, sp + /* Simplify the loop */ + sub r6, #1 +3: + /* Restore our magic value every time */ + str r5, [sp] + /* Move on to the next byte */ + add r6, #1 + + /* swp it in */ + mov r0, r6 + mov r1, #3 + swpb r0, r1, [r0] + + /* Check the old value */ + cmp r0, #0xc0 + bne 6f + + /* Check the stack value */ + ldrb r0, [r6] + cmp r0, #0x03 + bne 6f + + /* Just loop over the rest of the word and check those values. */ + mov r1, r6 + sub r1, sp + + mov r0, #0x00 +4: + cmp r0, r1 + beq 5f + + /* Check the next byte */ + ldrb r3, [sp, r0] + cmp r3, #0xc0 + bne 6f + +5: + add r0, #0x01 + cmp r0, #0x04 + /* Hit the end, this one succeeded */ + beq 7f + + /* Move on to the next byte */ + b 4b + +6: + /* Denote the failed test */ + add r4, #1 + /* "No" part of the notification */ + movw r0, :lower16:.L.boknot + movt r0, :upper16:.L.boknot + ldr r1, =(.L.boknotEnd - .L.boknot - 1) + bl print + + /* FALLTHROUGH */ +7: + /* "ok" part */ + movw r0, :lower16:.L.bok + movt r0, :upper16:.L.bok + ldr r1, =(.L.bokEnd - .L.bok - 1) + bl print + + /* test number */ + mov r0, r6 + sub r0, sp + add r0, #0x32 /* "0" + 2 because we start at test 2. */ + mov r1, #0x01 + str r0, [sp] + mov r0, sp + bl print + + /* boklabel */ + movw r0, :lower16:.L.boklabel + movt r0, :upper16:.L.boklabel + ldr r1, =(.L.boklabelEnd - .L.boklabel - 1) + bl print + + /* index */ + mov r0, r6 + sub r0, sp + add r0, #0x30 /* "0" */ + str r0, [sp] + mov r0, sp + mov r1, #0x01 + bl print + + /* bokterm */ + movw r0, :lower16:.L.bokterm + movt r0, :upper16:.L.bokterm + ldr r1, =(.L.boktermEnd - .L.bokterm - 1) + bl print + + mov r0, sp + add r0, #0x3 + cmp r0, r6 + bne 3b + + mov r0, r4 /* retval */ + ldr r7, =SYS_exit + swi 0 + + .p2align 2 + .type print,%function + .code 32 +print: + /* r0 - string, r1 = size */ + mov r2, r1 + mov r1, r0 + ldr r0, =STDOUT_FILENO + ldr r7, =SYS_write + swi 0 + + bx lr + +.L.testheader: + .asciz "1..5\n" +.L.testheaderEnd: + .size .L.testheader, .L.testheaderEnd - .L.testheader + + /* Maybe not the most efficient, but meh. */ +.L.ok1: + .asciz "ok 1 - swp\n" +.L.ok1End: + .size .L.ok1, .L.ok1End - .L.ok1 + +.L.boknot: + .asciz "not " +.L.boknotEnd: + .size .L.boknot, .L.boknotEnd - .L.boknot +.L.bok: + .asciz "ok " +.L.bokEnd: + .size .L.bok, .L.bokEnd - .L.bok +.L.boklabel: + .asciz " - swpb[" +.L.boklabelEnd: + .size .L.boklabel, .L.boklabelEnd - .L.boklabel +.L.bokterm: + .asciz "]\n" +.L.boktermEnd: + .size .L.bokterm, .L.boktermEnd - .L.bokterm diff --git a/tools/regression/compat32/aarch64/Makefile b/tools/regression/compat32/aarch64/Makefile new file mode 100644 index 000000000000..34428a58caa1 --- /dev/null +++ b/tools/regression/compat32/aarch64/Makefile @@ -0,0 +1,4 @@ +ACFLAGS= -target armv7-unknown-freebsd${OS_REVISION} -nostdlib -Wl,-e -Wl,main -static -mhwdiv=arm + +swp_test_impl: swp_test_impl.S + ${CC} ${ACFLAGS} -o ${.TARGET} ${.ALLSRC} diff --git a/tools/regression/compat32/aarch64/swp_test_impl.S b/tools/regression/compat32/aarch64/swp_test_impl.S new file mode 100644 index 000000000000..9f28ab17748e --- /dev/null +++ b/tools/regression/compat32/aarch64/swp_test_impl.S @@ -0,0 +1,410 @@ +/* + * SPDX-License-Identifier: BSD-2-Clause + * + * Copyright (c) 2021 Warner Losh + * Copyright (c) 2023 Stormshield + * Copyright (c) 2023 Klara, Inc. + */ + +#include + +#define STDOUT_FILENO 1 + +#define MUTEX_LOCKED 0x01 +#define MUTEX_UNLOCKED 0x00 + +#define STACK_SIZE 4096 +#define TLS_SIZE 4096 + + .text + .file "swp_test.S" + .syntax unified + .globl main + .p2align 2 + .type main,%function + .code 32 + +main: + /* + * Stack slots: + * 0 - Sync word + * 1 - Thread id + * 2 - Shared word + */ + sub sp, sp, #12 + + /* Print a message */ + movw r0, :lower16:.L.mainmsg + movt r0, :upper16:.L.mainmsg + ldr r1, =(.L.mainmsgEnd - .L.mainmsg - 1) + bl print + + /* Create two secondary threads */ + mov r0, #1 + str r0, [sp, #4] /* Thread ID */ + movw r0, :lower16:secondary_thread + movt r0, :upper16:secondary_thread + mov r1, sp + movw r2, :lower16:stack1 + movt r2, :upper16:stack1 + movw r3, :lower16:tls1 + movt r3, :upper16:tls1 + bl create_thr + +1: + /* + * Wait for the first new thread to ack its existence by + * incrementing the thread id. + */ + ldr r0, [sp, #4] + cmp r0, #1 + bne 2f + ldr r7, =SYS_sched_yield + swi 0 + b 1b + +2: + /* Create thread #2 */ + movw r0, :lower16:secondary_thread + movt r0, :upper16:secondary_thread + mov r1, sp + movw r2, :lower16:stack2 + movt r2, :upper16:stack2 + movw r3, :lower16:tls2 + movt r3, :upper16:tls2 + bl create_thr + +3: + /* + * Wait for the first new thread to ack its existence by + * incrementing the thread id. + */ + ldr r0, [sp, #4] + cmp r0, #2 + bne 4f + ldr r7, =SYS_sched_yield + swi 0 + b 3b + + /* Loop */ +4: + mov r0, sp + mov r1, #0 /* Thread loop */ + add r2, sp, #8 + bl thread_loop + b 4b + + /* UNREACHABLE */ + mov r0, #0 + ldr r7, =SYS_exit + swi 0 + + .p2align 2 + .type secondary_thread,%function + .code 32 +secondary_thread: + /* + * On entry, r0 is where we stashed our sync word and + * ack word (thread ID). + * + * Stash the sync word in r4, thread ID in r5. + */ + mov r4, r0 + ldr r5, [r0, #4] + + /* Print a message */ + movw r0, :lower16:.L.secondarymsg + movt r0, :upper16:.L.secondarymsg + ldr r1, =(.L.secondarymsgEnd - .L.secondarymsg - 1) + bl print + + /* Acknowledge that we started */ + add r0, r5, #1 + str r0, [r4, #4] + +1: + mov r0, r4 + mov r1, r5 + add r2, r4, #8 + bl thread_loop + b 1b + + .p2align 2 + .type thread_loop,%function + .code 32 +thread_loop: + push {r4, r5, r6, r7, r8, lr} + + /* + * r0 == sync word + * r1 == thread ID + * r2 == shared word + */ + mov r4, r0 + mov r5, r1 + mov r6, r2 + bl lock_mutex_swp + str r5, [r6] /* Write the thread ID */ + bl random_cycles + + # Save off the now cycle count */ + mov r8, r0 + + /* Print the thread ID and cycle count */ + mov r0, r5 + mov r1, #0 + bl printnum + + /* Separator */ + movw r0, :lower16:.L.idsep + movt r0, :upper16:.L.idsep + ldr r1, =(.L.idsepEnd - .L.idsep - 1) *** 249 LINES SKIPPED ***