diff --git a/config/semihosting-app.yaml b/config/semihosting-app.yaml new file mode 100644 index 0000000000000000000000000000000000000000..8531a5306d6e2a985672e91225e987c915fb2d09 --- /dev/null +++ b/config/semihosting-app.yaml @@ -0,0 +1,24 @@ +# Copyright (c) 2024, Arm Limited. +# SPDX-License-Identifier: MIT + +%YAML 1.2 +--- +description: >- + Arm Architecture Envelope Model FVP configured for experimenting with SME2 + in baremetal mode. + +run: + name: FVP_Base_RevC-2xAEMvA + + rtvars: + PROGRAM: + type: path + value: "" + ARGS: + type: str + value: "" + + params: + --application cluster0.cpu0: ${rtvar:PROGRAM} + -C cluster0.cpu0.semihosting-cmd_line: "\"${rtvar:PROGRAM} ${rtvar:ARGS}\"" + diff --git a/config/tarmac-trace.yaml b/config/tarmac-trace.yaml new file mode 100644 index 0000000000000000000000000000000000000000..fc8e13c93e0fc9bfc9fafdb08887f85cac6f4210 --- /dev/null +++ b/config/tarmac-trace.yaml @@ -0,0 +1,22 @@ +# Copyright (c) 2024, Arm Limited. +# SPDX-License-Identifier: MIT + +%YAML 1.2 +--- +description: >- + Make the FVP emit a tarmac trace. + +run: + + rtvars: + TARMAC_TRACE_FILE: + type: path + value: "trace.tarmac" + + params: + # Enable Tarmac trace. Use some leading spaces to fool shrinkwrap's handling of plugins and + # reduce the likelyhood of a clash with another plugin requested by another overlay or a + # user defined yaml configuration file. + ' --plugin': $$(dirname $$(which FVP_Base_RevC-2xAEMvA))/../../plugins/$$(basename $$(dirname $$(which FVP_Base_RevC-2xAEMvA)))/TarmacTrace.so + -C TRACE.TarmacTrace.trace-file: ${rtvar:TARMAC_TRACE_FILE} + diff --git a/docker/Dockerfile.full b/docker/Dockerfile.full index e007691f2d934dda1762cf50ab857ceaa15f0a11..1c04f8309bf925d41c82ca9051c4ac3e77915b01 100644 --- a/docker/Dockerfile.full +++ b/docker/Dockerfile.full @@ -72,3 +72,15 @@ RUN apt-get install --assume-yes --no-install-recommends --option=debug::pkgProb libasound-dev:arm64 \ liburing-dev:arm64 \ libz-dev:arm64 + +# Install the LLVM ET toolchain. +ARG TCH_LLVM_ET_PKG_NAME +ARG TCH_LLVM_ET_PATH +COPY assets/${TCH_LLVM_ET_PKG_NAME} /tools/. +RUN cd /tools \ + && if [ "${TCH_LLVM_ET_PKG_NAME}" != "none" ]; then \ + tar xf ${TCH_LLVM_ET_PKG_NAME}; \ + fi \ + && rm ${TCH_LLVM_ET_PKG_NAME} \ + && cd - +ENV TCH_LLVM_ET_PATH="/tools/${TCH_LLVM_ET_PATH}" diff --git a/docker/build.sh b/docker/build.sh index 48f5fd755d534ab9fb48026b5dc9fcedf21b3e81..ca231466d96b2961ca864d214ff21009f0c23710 100755 --- a/docker/build.sh +++ b/docker/build.sh @@ -105,6 +105,9 @@ if [ "${ARCH}" = "x86_64" ]; then TCH_LLVM_PKG_URL=https://github.com/llvm/llvm-project/releases/download/llvmorg-15.0.6 TCH_LLVM_PKG_NAME=clang+llvm-15.0.6-x86_64-linux-gnu-ubuntu-18.04.tar.xz TCH_LLVM_PATH=clang+llvm-15.0.6-x86_64-linux-gnu-ubuntu-18.04/bin + TCH_LLVM_ET_PKG_URL=https://github.com/ARM-software/LLVM-embedded-toolchain-for-Arm/releases/download/release-18.1.3 + TCH_LLVM_ET_PKG_NAME=LLVM-ET-Arm-18.1.3-Linux-x86_64.tar.xz + TCH_LLVM_ET_PATH=LLVM-ET-Arm-18.1.3-Linux-x86_64 TCH_PKG_URL_AARCH32=https://developer.arm.com/-/media/Files/downloads/gnu/13.2.rel1/binrel TCH_PKG_NAME_AARCH32=arm-gnu-toolchain-13.2.rel1-x86_64-arm-none-eabi.tar.xz TCH_PATH_AARCH32=arm-gnu-toolchain-13.2.Rel1-x86_64-arm-none-eabi/bin @@ -119,6 +122,9 @@ elif [ "${ARCH}" = "aarch64" ] || [ "${ARCH}" = "arm64" ]; then TCH_LLVM_PKG_URL=https://github.com/llvm/llvm-project/releases/download/llvmorg-15.0.6 TCH_LLVM_PKG_NAME=clang+llvm-15.0.6-aarch64-linux-gnu.tar.xz TCH_LLVM_PATH=clang+llvm-15.0.6-aarch64-linux-gnu/bin + TCH_LLVM_ET_PKG_URL=https://github.com/ARM-software/LLVM-embedded-toolchain-for-Arm/releases/download/release-18.1.3 + TCH_LLVM_ET_PKG_NAME=LLVM-ET-Arm-18.1.3-Linux-Aarch64.tar.xz + TCH_LLVM_ET_PATH=LLVM-ET-Arm-18.1.3-Linux-AArch64 TCH_PKG_URL_AARCH32=https://developer.arm.com/-/media/Files/downloads/gnu/13.2.rel1/binrel TCH_PKG_NAME_AARCH32=arm-gnu-toolchain-13.2.rel1-aarch64-arm-none-eabi.tar.xz TCH_PATH_AARCH32=arm-gnu-toolchain-13.2.Rel1-aarch64-arm-none-eabi/bin @@ -151,6 +157,7 @@ cd ${ROOT} mkdir -p assets wget_or_cache assets/${TCH_PKG_NAME_AARCH64} ${TCH_PKG_URL_AARCH64}/${TCH_PKG_NAME_AARCH64} wget_or_cache assets/${TCH_LLVM_PKG_NAME} ${TCH_LLVM_PKG_URL}/${TCH_LLVM_PKG_NAME} +wget_or_cache assets/${TCH_LLVM_ET_PKG_NAME} ${TCH_LLVM_ET_PKG_URL}/${TCH_LLVM_ET_PKG_NAME} wget_or_cache assets/${TCH_PKG_NAME_AARCH32} ${TCH_PKG_URL_AARCH32}/${TCH_PKG_NAME_AARCH32} wget_or_cache assets/${FVP_PKG_NAME} ${FVP_PKG_URL}/${FVP_PKG_NAME} @@ -181,6 +188,8 @@ if [ "${DRIVER}" = "docker" ]; then --build-arg=TCH_PATH_AARCH32=${TCH_PATH_AARCH32} \ --build-arg=TCH_LLVM_PKG_NAME=${TCH_LLVM_PKG_NAME} \ --build-arg=TCH_LLVM_PATH=${TCH_LLVM_PATH} \ + --build-arg=TCH_LLVM_ET_PKG_NAME=${TCH_LLVM_ET_PKG_NAME} \ + --build-arg=TCH_LLVM_ET_PATH=${TCH_LLVM_ET_PATH} \ --file=Dockerfile.full \ --tag=${REGISTRY}/base-full-nofvp:${VERSION}-${ARCH} \ . @@ -227,6 +236,8 @@ elif [ "${DRIVER}" = "kaniko" ]; then --build-arg=TCH_PATH_AARCH32=${TCH_PATH_AARCH32} \ --build-arg=TCH_LLVM_PKG_NAME=${TCH_LLVM_PKG_NAME} \ --build-arg=TCH_LLVM_PATH=${TCH_LLVM_PATH} \ + --build-arg=TCH_LLVM_ET_PKG_NAME=${TCH_LLVM_ET_PKG_NAME} \ + --build-arg=TCH_LLVM_ET_PATH=${TCH_LLVM_ET_PATH} \ --dockerfile=Dockerfile.full \ --destination=${REGISTRY}/base-full-nofvp:${VERSION}-${ARCH} \ --context=. diff --git a/test/genassets.sh b/test/genassets.sh index bb3a9b987c51127e41ab7d8b2aef1bea1e32db55..42458da90e14252a530971bd8b93575a5bdfbc1e 100755 --- a/test/genassets.sh +++ b/test/genassets.sh @@ -16,7 +16,7 @@ The following parameters are valid: -h Show this help -R Specify the choice for shrinkwrap runtime. Defaults to 'docker' -n Dryrun mode for shrinkwrap build - -v Versbose mode for shrinkwrap build + -v Verbose mode for shrinkwrap build " RUNTIME=docker diff --git a/test/test.py b/test/test.py index e39b59ed654285ef7278c99074da9b4846db49ca..1b09efd3f143d60eee6db7da0294957aed5b1ce4 100755 --- a/test/test.py +++ b/test/test.py @@ -15,8 +15,7 @@ from xml.sax.saxutils import escape, quoteattr import yaml -RUNTIME = None -IMAGE = None +RT = None FVPJOBS = None @@ -27,6 +26,20 @@ KERNEL = os.path.join(ASSETS, 'Image') BOOTWRAPPER = os.path.join(ASSETS, 'linux-system.axf') ROOTFS = os.path.join(ASSETS, 'rootfs.ext4') +# Look for local tests in $CWD/tests, and add them to SHRINKWRAP_CONFIG. +TESTS_DIR = os.path.join(SCRIPTDIR, 'tests') +SHRINKWRAP_CONFIG = list() +os_shrinkwrap_config = os.getenv('SHRINKWRAP_CONFIG') +if os_shrinkwrap_config: + SHRINKWRAP_CONFIG.append(os_shrinkwrap_config) + +for dirname in os.listdir(TESTS_DIR): + dir = os.path.join(TESTS_DIR, dirname) + if os.path.isdir(dir): + SHRINKWRAP_CONFIG.append(dir) + +if SHRINKWRAP_CONFIG: + os.putenv('SHRINKWRAP_CONFIG', ':'.join(SHRINKWRAP_CONFIG)) ARCH_LATEST = 'v9.5' CONFIGS = [ @@ -128,6 +141,11 @@ CONFIGS = [ }, }, }, + { + 'config': 'HelloWorld.yaml', + 'btvars': {}, + 'rtvars': {}, + }, ] @@ -254,7 +272,6 @@ def build_configs(configs, overlay=None, btvarss=None): status = 'pass' error = None - rt = f'-R {RUNTIME} -I {IMAGE}' cleanargs = f'{" ".join(configs)} {f"-o {overlay}" if overlay else ""}' if btvarss is None: @@ -279,8 +296,8 @@ def build_configs(configs, overlay=None, btvarss=None): buildargs = f'{tmpfilename} {f"-o {overlay}" if overlay else ""}' try: - run(f'shrinkwrap {rt} clean {cleanargs}', None) - run(f'shrinkwrap {rt} buildall {buildargs}', None) + run(f'shrinkwrap {RT} clean {cleanargs}', None) + run(f'shrinkwrap {RT} buildall {buildargs}', None) except Exception as e: status = 'fail' error = str(e) @@ -296,7 +313,7 @@ def build_configs(configs, overlay=None, btvarss=None): } for config, btvars in zip(configs, btvarss)] -def run_config(config, overlay, rtvars, tag, capture): +def run_config(config, rt, overlay, rtvars, tag, capture): def make_rtcmds(rtvars): return ' '.join([f'-r {k}={v}' for k, v in rtvars.items()]) @@ -313,7 +330,6 @@ def run_config(config, overlay, rtvars, tag, capture): 'tag': tag, } - rt = f'-R {RUNTIME} -I {IMAGE}' overlay = f'-o {overlay}' if overlay else '' args = f'{config} {overlay} {runargs}' @@ -339,7 +355,7 @@ def run_configs(configs, overlay=None, rtvarss=None): params = [] for config, _rtvars in zip(configs, rtvarss): for tag, rtvars in _rtvars.items(): - params.append((config, overlay, rtvars, tag, FVPJOBS > 1)) + params.append((config, RT, overlay, rtvars, tag, FVPJOBS > 1)) with mp.Pool(processes=FVPJOBS) as pool: for result, stdout in pool.starmap(run_config, params): @@ -422,11 +438,9 @@ def main(): args = parser.parse_args() - global RUNTIME - global IMAGE + global RT global FVPJOBS - RUNTIME = args.runtime - IMAGE = args.image + RT = f'-R {args.runtime} -I {args.image}' FVPJOBS = args.fvpjobs do_main(args) diff --git a/test/tests/HelloWorld/HelloWorld.yaml b/test/tests/HelloWorld/HelloWorld.yaml new file mode 100644 index 0000000000000000000000000000000000000000..4ea60b9a1aae6aeb56f98e1600473e1dd903f783 --- /dev/null +++ b/test/tests/HelloWorld/HelloWorld.yaml @@ -0,0 +1,39 @@ +# Copyright (c) 2024, Arm Limited. +# SPDX-License-Identifier: MIT + +%YAML 1.2 +--- +description: >- + An example baremetal app, the famous 'Hello, world !'. + +layers: + - arch/v9.2.yaml + - semihosting-app.yaml + +concrete: true + +build: + + HelloWorld: + sourcedir: ${param:configdir} + + build: + - make BUILD_DIR=${param:builddir} + + artifacts: + PROGRAM: ${param:builddir}/hello + +run: + + params: + -C bp.secure_memory: 0 + + # FVP Performance tweaks. + -C cache_state_modelled: 0 # Disable d-cache and i-cache state for all components + -C cluster0.check_memory_attributes: 0 # Disable checking that SW-set memory attributes conform to architecturally required constraints + -C cluster1.check_memory_attributes: 0 + + # Misc FVP controls. + -C bp.vis.disable_visualisation: 1 + -C bp.ve_sysregs.exit_on_shutdown: 1 # SYS_CFG_SHUTDOWN exits simulation + --stat: null diff --git a/test/tests/HelloWorld/Makefile b/test/tests/HelloWorld/Makefile new file mode 100644 index 0000000000000000000000000000000000000000..fd047db75db1e1f610fa66c9f1e6ac0480b998a9 --- /dev/null +++ b/test/tests/HelloWorld/Makefile @@ -0,0 +1,24 @@ +ifndef TCH_LLVM_ET_PATH +$(error TCH_LLVM_ET_PATH is not set) +endif + +ifndef BUILD_DIR +$(error BUILD_DIR is not set) +endif + +CC=${TCH_LLVM_ET_PATH}/bin/clang + +CFLAGS=--target=aarch64-none-elf -march=armv9.2-a -fno-exceptions -fno-rtti -std=c99 -O2 -Wall +LDFLAGS=-lcrt0-semihost -lsemihost -Wl,--defsym=__boot_flash=0x80000000 -Wl,--defsym=__flash=0x80001000 -Wl,--defsym=__ram=0x81000000 -T picolibc.ld + +all: ${BUILD_DIR}/hello + +${BUILD_DIR}/%: %.c + ${CC} ${CFLAGS} ${LDFLAGS} -o $@ $< + +.PHONY: clean realclean +clean: + -rm ${BUILD_DIR}/hello ${BUILD_DIR}/*.o + +realclean: + -rm -Rf ${BUILD_DIR} diff --git a/test/tests/HelloWorld/hello.c b/test/tests/HelloWorld/hello.c new file mode 100644 index 0000000000000000000000000000000000000000..28ecea9b903efd6cefb910040d7b10674d553015 --- /dev/null +++ b/test/tests/HelloWorld/hello.c @@ -0,0 +1,7 @@ +#include +#include + +int main(int argc, char *argv[]) { + printf("Hello, world !\n"); + return EXIT_SUCCESS; +}