diff --git a/.devcontainer/ubuntu-24.04/Dockerfile b/.devcontainer/ubuntu-24.04/Dockerfile index fa9f4a4f7..045e1b9c9 100644 --- a/.devcontainer/ubuntu-24.04/Dockerfile +++ b/.devcontainer/ubuntu-24.04/Dockerfile @@ -22,6 +22,7 @@ RUN apt-get update && \ llvm-18-tools \ locales \ nano \ + qemu-system-arm \ software-properties-common \ sudo \ unzip && \ @@ -39,6 +40,7 @@ RUN apt-get update && \ ENV LANG=en_US.UTF-8 ENV LC_ALL=en_US.UTF-8 ENV VIRTUAL_ENV=/opt/cmsis-python +ENV VCPKG_DOWNLOADS=/var/cache/vcpkg ENV PATH="${VIRTUAL_ENV}/bin:${PATH}" RUN python3.14 -m venv "${VIRTUAL_ENV}" && \ @@ -60,8 +62,8 @@ RUN userdel --remove ubuntu && \ echo "${USERNAME} ALL=(root) NOPASSWD:ALL" > "/etc/sudoers.d/${USERNAME}" && \ chmod 0440 "/etc/sudoers.d/${USERNAME}" -RUN mkdir -p /workspaces && \ - chown "${USERNAME}:${USERNAME}" /workspaces +RUN mkdir -p /workspaces "${VCPKG_DOWNLOADS}" && \ + chown "${USERNAME}:${USERNAME}" /workspaces "${VCPKG_DOWNLOADS}" COPY vcpkg-configuration.json /home/ COPY postCreateCommand.sh /home/ diff --git a/.devcontainer/ubuntu-24.04/devcontainer.json b/.devcontainer/ubuntu-24.04/devcontainer.json index 81e9cb8a1..3d37ff220 100644 --- a/.devcontainer/ubuntu-24.04/devcontainer.json +++ b/.devcontainer/ubuntu-24.04/devcontainer.json @@ -9,6 +9,7 @@ "remoteUser": "${localEnv:USER}", "mounts": [ "source=${devcontainerId}-home,target=/home/${localEnv:USER},type=volume", + "source=cmsis-6-vcpkg-cache,target=/var/cache/vcpkg,type=volume", "source=${localEnv:HOME}${localEnv:USERPROFILE}/.ssh,target=/home/${localEnv:USER}/.ssh,type=bind,consistency=cached", "source=${localEnv:HOME}${localEnv:USERPROFILE}/.armlm,target=/home/${localEnv:USER}/.armlm,type=bind,consistency=cached", "source=${localEnv:HOME}${localEnv:USERPROFILE}/.iarlm,target=/home/${localEnv:USER}/.iarlm,type=bind,consistency=cached" diff --git a/.devcontainer/ubuntu-24.04/postCreateCommand.sh b/.devcontainer/ubuntu-24.04/postCreateCommand.sh index b01848575..7ab9ff3a3 100644 --- a/.devcontainer/ubuntu-24.04/postCreateCommand.sh +++ b/.devcontainer/ubuntu-24.04/postCreateCommand.sh @@ -1,5 +1,13 @@ #!/bin/bash +VCPKG_CACHE_DIR="${VCPKG_DOWNLOADS:-/var/cache/vcpkg}" + +echo "Preparing shared vcpkg cache at ${VCPKG_CACHE_DIR} ..." +sudo mkdir -p "${VCPKG_CACHE_DIR}" +if [ "$(stat -c '%u' "${VCPKG_CACHE_DIR}")" -ne "$(id -u)" ]; then + sudo chown -R "$(id -u):$(id -g)" "${VCPKG_CACHE_DIR}" +fi + echo "Installing oh-my-bash ..." bash -c "$(curl -fsSL https://raw.githubusercontent.com/ohmybash/oh-my-bash/master/tools/install.sh)" --unattended sed -i 's/OSH_THEME="font"/OSH_THEME="powerline"/' ~/.bashrc diff --git a/.gitignore b/.gitignore index ea71c30d1..b508ea995 100644 --- a/.gitignore +++ b/.gitignore @@ -22,3 +22,4 @@ output linkchecker-out.csv .DS_STORE *.tmp +.qlty diff --git a/AGENTS.md b/AGENTS.md new file mode 100644 index 000000000..d386601ab --- /dev/null +++ b/AGENTS.md @@ -0,0 +1,37 @@ +# Repository agent instructions + +## Test verification + +- Run CMSIS-Core tests in the Ubuntu 24.04 dev container. Do not install test + dependencies on the host. +- Read [`TESTING.md`](TESTING.md) before selecting or running tests. It contains + the container setup, matrix syntax, supported values, and license caveats. +- Inspect the diff and run the smallest matrix that exercises the changed code. + Do not run the complete matrix by default. Documentation-only changes do not + require firmware tests unless they alter commands or test configuration. +- When CMSIS tests are relevant, select at least an affected core, a compiler, + and an optimization level. Start with GCC and `none` unless the change points + to a different combination. +- Expand the selection when applicable: + - Add Clang for shared compiler abstractions, intrinsics, or inline assembly. + - Add AC6 for Arm Compiler-specific paths when the required license is + available. + - Add `speed`, `size`, or all optimization levels for code-generation or + optimization-sensitive changes. + - Add secure and non-secure variants for TrustZone changes. + - Add representative M-profile generations for shared Core-M changes. + - Add the affected A-profile or R-profile core for Core-A or Core-R changes. + - Run CoreValidation `build run` when runtime behavior, startup, system, + exception, interrupt, or security behavior may have changed. +- Quote wildcard selectors such as `-d "CM33*"` so the shell does not expand + them. Repeat `-c`, `-d`, or `-o` to select multiple values. +- Build a CoreValidation configuration before running it. `build run` is the + preferred form for a fresh verification. +- If a requested compiler, model, or core is blocked by a missing tool or + license, record the exact blocker and continue with the other relevant + configurations. Do not report an environment blocker as a source failure. +- Before handoff, report the exact commands and matrix combinations run, their + pass/fail/skip totals, any filtered or blocked combinations, and whether the + worktree gained generated files. +- Preserve pre-existing worktree changes. Remove only generated files created + by the current test run, after confirming their paths with `git status`. diff --git a/CMSIS/CoreValidation/Layer/Target/CA9QEMU/Config/mem_ARMCA9.h b/CMSIS/CoreValidation/Layer/Target/CA9QEMU/Config/mem_ARMCA9.h new file mode 100644 index 000000000..3f8ab1159 --- /dev/null +++ b/CMSIS/CoreValidation/Layer/Target/CA9QEMU/Config/mem_ARMCA9.h @@ -0,0 +1,35 @@ +/**************************************************************************//** + * @file mem_ARMCA9.h + * @brief QEMU vexpress-a9 memory regions used by the linker and MMU + ****************************************************************************** + * SPDX-License-Identifier: Apache-2.0 + */ + +/* Copyright (c) 2026 Arm Limited. All rights reserved. */ + +#ifndef __MEM_ARMCA9_H +#define __MEM_ARMCA9_H + +/* QEMU vexpress-a9 high memory starts at 0x60000000. */ +#define __ROM_BASE 0x60000000 +#define __ROM_SIZE 0x00200000 + +#define __RAM_BASE 0x60200000 +#define __RAM_SIZE 0x00200000 + +#define __RW_DATA_SIZE 0x00100000 +#define __ZI_DATA_SIZE 0x000F0000 + +#define __STACK_SIZE 0x00001000 +#define __HEAP_SIZE 0x00008000 + +#define __UND_STACK_SIZE 0x00000100 +#define __ABT_STACK_SIZE 0x00000100 +#define __SVC_STACK_SIZE 0x00000100 +#define __IRQ_STACK_SIZE 0x00000100 +#define __FIQ_STACK_SIZE 0x00000100 + +#define __TTB_BASE 0x60500000 +#define __TTB_SIZE 0x00004000 + +#endif /* __MEM_ARMCA9_H */ diff --git a/CMSIS/CoreValidation/Layer/Target/CA9QEMU/Include/ARMCA9.h b/CMSIS/CoreValidation/Layer/Target/CA9QEMU/Include/ARMCA9.h new file mode 100644 index 000000000..d0d7d458c --- /dev/null +++ b/CMSIS/CoreValidation/Layer/Target/CA9QEMU/Include/ARMCA9.h @@ -0,0 +1,96 @@ +/**************************************************************************//** + * @file ARMCA9.h + * @brief CMSIS-Core(A) device header for QEMU vexpress-a9 + ****************************************************************************** + * SPDX-License-Identifier: Apache-2.0 + */ + +/* Copyright (c) 2026 Arm Limited. All rights reserved. */ + +#ifndef ARMCA9_H +#define ARMCA9_H + +#ifdef __cplusplus +extern "C" { +#endif + +typedef enum IRQn +{ + SGI0_IRQn = 0, + SGI1_IRQn = 1, + SGI2_IRQn = 2, + SGI3_IRQn = 3, + SGI4_IRQn = 4, + SGI5_IRQn = 5, + SGI6_IRQn = 6, + SGI7_IRQn = 7, + SGI8_IRQn = 8, + SGI9_IRQn = 9, + SGI10_IRQn = 10, + SGI11_IRQn = 11, + SGI12_IRQn = 12, + SGI13_IRQn = 13, + SGI14_IRQn = 14, + SGI15_IRQn = 15, + + GlobalTimer_IRQn = 27, + PrivTimer_IRQn = 29, + PrivWatchdog_IRQn = 30, + + Watchdog_IRQn = 32, + Timer0_IRQn = 34, + Timer1_IRQn = 35, + RTClock_IRQn = 36, + UART0_IRQn = 37, + UART1_IRQn = 38, + UART2_IRQn = 39, + UART3_IRQn = 40, + MCI0_IRQn = 41, + MCI1_IRQn = 42, + AACI_IRQn = 43, + Keyboard_IRQn = 44, + Mouse_IRQn = 45, + CLCD_IRQn = 46, + Ethernet_IRQn = 47, + VFS2_IRQn = 73, +} IRQn_Type; + +/* QEMU vexpress-a9 private peripheral region. */ +#define VEXPRESS_A9_PRIVATE_BASE (0x1E000000UL) +#define GIC_DISTRIBUTOR_BASE (VEXPRESS_A9_PRIVATE_BASE + 0x00001000UL) +#define GIC_INTERFACE_BASE (VEXPRESS_A9_PRIVATE_BASE + 0x00000100UL) +#define TIMER_BASE (VEXPRESS_A9_PRIVATE_BASE + 0x00000600UL) +#define L2C_310_BASE (VEXPRESS_A9_PRIVATE_BASE + 0x0000A000UL) + +#if defined (__CC_ARM) + #pragma push + #pragma anon_unions +#elif defined (__ICCARM__) + #pragma language=extended +#elif defined(__ARMCC_VERSION) && (__ARMCC_VERSION >= 6010050) + #pragma clang diagnostic push + #pragma clang diagnostic ignored "-Wc11-extensions" + #pragma clang diagnostic ignored "-Wreserved-id-macro" +#endif + +#define __CA_REV 0x0000U +#define __CORTEX_A 9U +#define __FPU_PRESENT 1U +#define __GIC_PRESENT 1U +#define __TIM_PRESENT 1U +#define __L2C_PRESENT 0U + +#include "core_ca.h" +#include + +#if defined (__CC_ARM) + #pragma pop +#elif defined(__ARMCC_VERSION) && (__ARMCC_VERSION >= 6010050) + #pragma clang diagnostic pop +#endif + +#ifdef __cplusplus +} +#endif + +#endif /* ARMCA9_H */ diff --git a/CMSIS/CoreValidation/Layer/Target/CA9QEMU/Source/mmu_ARMCA9.c b/CMSIS/CoreValidation/Layer/Target/CA9QEMU/Source/mmu_ARMCA9.c new file mode 100644 index 000000000..73bb092d3 --- /dev/null +++ b/CMSIS/CoreValidation/Layer/Target/CA9QEMU/Source/mmu_ARMCA9.c @@ -0,0 +1,55 @@ +/**************************************************************************//** + * @file mmu_ARMCA9.c + * @brief MMU configuration for QEMU vexpress-a9 + ****************************************************************************** + * SPDX-License-Identifier: Apache-2.0 + */ + +/* Copyright (c) 2026 Arm Limited. All rights reserved. */ + +#include "ARMCA9.h" +#include "mem_ARMCA9.h" + +#define TTB_BASE ((uint32_t *)__TTB_BASE) +#define VEXPRESS_A9_RAM_BASE (0x60000000U) +#define VEXPRESS_A9_RAM_SIZE (0x08000000U) + +static uint32_t Sect_Normal_Cod; +static uint32_t Sect_Normal_RW; +static uint32_t Sect_Device_RO; +static uint32_t Sect_Device_RW; + +void MMU_CreateTranslationTable(void) +{ + mmu_region_attributes_Type region; + + /* Start with a faulting 4 GB address space. */ + MMU_TTSection(TTB_BASE, 0U, 4096U, DESCRIPTOR_FAULT); + + section_normal_cod(Sect_Normal_Cod, region); + section_normal_rw(Sect_Normal_RW, region); + section_device_ro(Sect_Device_RO, region); + section_device_rw(Sect_Device_RW, region); + + /* + * Identity-map all high memory. QEMU's semihosting SYS_HEAPINFO places + * the C library stack near the top of this 128 MiB region. + */ + MMU_TTSection(TTB_BASE, VEXPRESS_A9_RAM_BASE, + VEXPRESS_A9_RAM_SIZE / 0x100000U, Sect_Normal_RW); + + /* Override the linked code region with read-only executable attributes. */ + MMU_TTSection(TTB_BASE, __ROM_BASE, __ROM_SIZE / 0x100000U, Sect_Normal_Cod); + + /* QEMU aliases its first 64 MiB flash bank at address zero. */ + MMU_TTSection(TTB_BASE, 0x00000000U, 64U, Sect_Device_RO); + + /* QEMU vexpress-a9 motherboard and Cortex-A9 private peripherals. */ + MMU_TTSection(TTB_BASE, 0x10000000U, 1U, Sect_Device_RW); + MMU_TTSection(TTB_BASE, VEXPRESS_A9_PRIVATE_BASE, 1U, Sect_Device_RW); + + __set_TTBR0(__TTB_BASE | 0x48U); + __ISB(); + __set_DACR(1U); + __ISB(); +} diff --git a/CMSIS/CoreValidation/Layer/Target/CA9QEMU/Target.clayer.yml b/CMSIS/CoreValidation/Layer/Target/CA9QEMU/Target.clayer.yml new file mode 100644 index 000000000..af9b46325 --- /dev/null +++ b/CMSIS/CoreValidation/Layer/Target/CA9QEMU/Target.clayer.yml @@ -0,0 +1,39 @@ +layer: + type: Target + description: Cortex-A9 target for QEMU vexpress-a9 + + components: + - component: ARM::CMSIS:CORE + - component: Device:IRQ Controller:GIC + + add-path: + - ./Config + - ./Include + - ../CA9/RTE/Device/ARMCA9 + + # QEMU TCG does not model dirty cache-line data that can be discarded. + define: + - TC_CAL1CACHE_INVALIDATEDCACHEALL: 0 + + linker: + - script: ../CA9/RTE/Device/ARMCA9/ARMCA9_ac6.sct + for-compiler: + - AC6 + - script: ../CA9/RTE/Device/ARMCA9/ARMCA9_gcc.ld + for-compiler: + - GCC + - script: ../CA9/RTE/Device/ARMCA9/ARMCA9_clang.ld + for-compiler: + - CLANG + - regions: Config/mem_ARMCA9.h + for-compiler: + - AC6 + - GCC + - CLANG + + groups: + - group: QEMU vexpress-a9 Startup + files: + - file: ../CA9/RTE/Device/ARMCA9/startup_ARMCA9.c + - file: ../CA9/RTE/Device/ARMCA9/system_ARMCA9.c + - file: ./Source/mmu_ARMCA9.c diff --git a/CMSIS/CoreValidation/Project/Validation.csolution.yml b/CMSIS/CoreValidation/Project/Validation.csolution.yml index 185969f28..ee8bfcb73 100644 --- a/CMSIS/CoreValidation/Project/Validation.csolution.yml +++ b/CMSIS/CoreValidation/Project/Validation.csolution.yml @@ -127,6 +127,10 @@ solution: - type: CA9 device: ARMCA9 + #Target: CA9 on QEMU vexpress-a9 + - type: CA9QEMU + device: ARMCA9 + build-types: - type: none optimize: none diff --git a/CMSIS/CoreValidation/Project/Validation/Validation.cproject.yml b/CMSIS/CoreValidation/Project/Validation/Validation.cproject.yml index ffa298856..8e43f4842 100644 --- a/CMSIS/CoreValidation/Project/Validation/Validation.cproject.yml +++ b/CMSIS/CoreValidation/Project/Validation/Validation.cproject.yml @@ -33,6 +33,7 @@ project: - +CA5 - +CA7 - +CA9 + - +CA9QEMU #Target: CM0 - layer: ../../Layer/Target/CM0/Target.clayer.yml @@ -163,3 +164,8 @@ project: - layer: ../../Layer/Target/CA9/Target.clayer.yml for-context: - +CA9 + + #Target: CA9 on QEMU vexpress-a9 + - layer: ../../Layer/Target/CA9QEMU/Target.clayer.yml + for-context: + - +CA9QEMU diff --git a/CMSIS/CoreValidation/Project/build.py b/CMSIS/CoreValidation/Project/build.py index 3ed71e8a7..4a8421913 100755 --- a/CMSIS/CoreValidation/Project/build.py +++ b/CMSIS/CoreValidation/Project/build.py @@ -45,6 +45,7 @@ class DeviceAxis(Enum): CA7 = ('Cortex-A7', 'CA7') CA7NEON = ('Cortex-A7neon', 'CA7neon') CA9 = ('Cortex-A9', 'CA9') + CA9QEMU = ('Cortex-A9 QEMU vexpress-a9', 'CA9QEMU') CA9NEON = ('Cortex-A9neon', 'CA9neon') CA35 = ('Cortex-A35', 'CA35') CA35NEON = ('Cortex-A35neon', 'CA35neon') @@ -170,13 +171,23 @@ class OptimizationAxis(Enum): } QEMU_MACHINE = { - DeviceAxis.CM3: ("mps2-an385"), - DeviceAxis.CM4: ("mps2-an386"), - DeviceAxis.CM7: ("mps2-an500"), - DeviceAxis.CM33: ("mps2-an505"), - DeviceAxis.CM55: ("mps3-an547") + DeviceAxis.CM3: ("mps2-an385", []), + DeviceAxis.CM4: ("mps2-an386", []), + DeviceAxis.CM7: ("mps2-an500", []), + DeviceAxis.CM33: ("mps2-an505", []), + DeviceAxis.CM55: ("mps3-an547", []), + DeviceAxis.CA9QEMU: ("vexpress-a9", [ + "-cpu", "cortex-a9", + "-smp", "1", + "-m", "128M", + "-audiodev", "none,id=audio0", + "-global", "pl041.audiodev=audio0", + ]), } +QEMU_ONLY_DEVICES = [DeviceAxis.CA9QEMU] + + def config_suffix(config, timestamp=True): suffix = f"{config.compiler[0]}-{config.optimize[0]}-{config.device[1]}" if timestamp: @@ -243,8 +254,12 @@ def extract(config): @matrix_action def run(config, results): """Run the selected configurations.""" - logging.info("Running Core Validation on Arm model ...") - yield model_exec(config) + if config.device in QEMU_ONLY_DEVICES: + logging.info("Running Core Validation on Qemu ...") + yield qemu_exec(config) + else: + logging.info("Running Core Validation on Arm model ...") + yield model_exec(config) try: results[0].test_report.write(f"build/CoreValidation-{config_suffix(config)}.junit") @@ -258,12 +273,20 @@ def run(config, results): @matrix_action def qemu(config, results): """Run the selected configurations.""" - if not config.device in QEMU_MACHINE: + if config.device not in QEMU_MACHINE: logging.error("Qemu doesn't support target device '%s'!", config.device) return logging.info("Running Core Validation on Qemu ...") yield qemu_exec(config) + try: + results[0].test_report.write(f"build/CoreValidation-{config_suffix(config)}.junit") + except RuntimeError as ex: + if isinstance(ex.__cause__, XMLSyntaxError): + logging.error("No valid test report found in model output!") + else: + logging.exception(ex) + @matrix_command() def cbuild_clean(project): @@ -311,8 +334,17 @@ def model_exec(config): f"{result.command.config.device}." f"{title}")) def qemu_exec(config): - cmdline = ["qemu-system-arm", "-semihosting-config", "enable=on", "-monitor", "none", "-serial", "none", "-nographic"] - cmdline += ["-machine", QEMU_MACHINE[config.device]] + machine, machine_args = QEMU_MACHINE[config.device] + cmdline = [ + "qemu-system-arm", + "-semihosting-config", "enable=on,target=native", + "-monitor", "none", + "-serial", "none", + "-nographic", + "-no-reboot", + ] + cmdline += ["-machine", machine] + cmdline += machine_args cmdline += ["-kernel", f"{build_dir(config)}/{output_dir(config)}/Validation.{config.compiler.image_ext}"] return cmdline diff --git a/CMSIS/CoreValidation/Source/ConfigA/CV_Config.h b/CMSIS/CoreValidation/Source/ConfigA/CV_Config.h index ddd51c6b6..5ea8f9aaf 100644 --- a/CMSIS/CoreValidation/Source/ConfigA/CV_Config.h +++ b/CMSIS/CoreValidation/Source/ConfigA/CV_Config.h @@ -107,7 +107,9 @@ // TC_CAL1Cache_log2_up #define TC_CAL1CACHE_LOG2_UP 1 // TC_CAL1Cache_InvalidateDCacheAll +#ifndef TC_CAL1CACHE_INVALIDATEDCACHEALL #define TC_CAL1CACHE_INVALIDATEDCACHEALL 1 +#endif // TC_CAL1Cache_CleanDCacheAll #define TC_CAL1CACHE_CLEANDCACHEALL 1 // TC_CAL1Cache_CleanInvalidateDCacheAll @@ -115,4 +117,3 @@ // #endif /* __CV_CONFIG_H */ - diff --git a/README.md b/README.md index caf9e9bb0..30b78bbc1 100644 --- a/README.md +++ b/README.md @@ -8,6 +8,7 @@ - [**Documentation of latest release**](https://arm-software.github.io/CMSIS_6/) - access to the CMSIS user's manual. - [**CMSIS Components**](https://arm-software.github.io/CMSIS_6/latest/General/index.html#cmsis_components) - overview of software, tools, and specification. +- [**Running tests**](./TESTING.md) - use the configured dev container and select a relevant Core test matrix. - [**Raise Issues**](https://github.com/ARM-software/CMSIS_6#issues-and-labels) - to provide feedback or report problems. - [**Documentation of main branch**](https://arm-software.github.io/CMSIS_6/main/General/index.html) - updated from time to time (use [Generate CMSIS Pack for Release](https://github.com/ARM-software/CMSIS_6#generate-cmsis-pack-for-release) for local generation). diff --git a/TESTING.md b/TESTING.md new file mode 100644 index 000000000..6e1dc34d6 --- /dev/null +++ b/TESTING.md @@ -0,0 +1,254 @@ +# Testing CMSIS-Core + +The repository has two complementary CMSIS-Core test suites: + +- `CMSIS/Core/Test`: compile and disassembly checks driven by LLVM LIT and + FileCheck. +- `CMSIS/CoreValidation`: projects that are built with CMSIS-Toolbox and run on + Arm Fixed Virtual Platforms (FVPs) or selected QEMU targets. + +Run both suites in the configured Ubuntu 24.04 dev container. The test matrix +is large, so select only the cores, compilers, and optimization levels relevant +to a change unless the complete matrix is explicitly required. + +## Start the dev container + +In VS Code, install the Dev Containers extension, open the repository, and run +**Dev Containers: Reopen in Container**. The configuration in +`.devcontainer/ubuntu-24.04` installs CMSIS-Toolbox, CMake, Ninja, LIT, +FileCheck, FVPs, QEMU, and the AC6, GCC, and LLVM/Clang toolchains. + +TI Arm Clang is installed separately in CI and is not part of this dev +container. + +Downloaded vcpkg archives and extracted tools are stored in the named Docker +volume `cmsis-6-vcpkg-cache`, mounted at `/var/cache/vcpkg`. The volume name is +stable across dev-container instances, so rebuilding or recreating the +container reuses the downloads. The first instance still needs to populate the +cache. + +In every new container shell, activate the environment from the location of the +dev-container vcpkg manifest before running tests: + +```bash +source "$HOME/.vcpkg/vcpkg-init" +pushd /home +vcpkg-shell activate +popd +``` + +Check the environment before the first run: + +```bash +cbuild --version +cbuild list environment +lit --version +``` + +### Apple Silicon + +The current vcpkg bootstrap selects x86-64 tooling. On an Arm-based Mac, run +the configured image as `linux/amd64`. A command-line fallback equivalent to +the dev-container setup is: + +```bash +docker build --platform linux/amd64 \ + --build-arg USERNAME="$(id -un)" \ + --tag cmsis-6-dev \ + .devcontainer/ubuntu-24.04 + +docker run --rm --interactive --tty --init --platform linux/amd64 \ + --mount type=bind,source="$PWD",target=/workspaces/CMSIS_6 \ + --mount type=volume,source=cmsis-6-dev-home,target="/home/$(id -un)" \ + --mount type=volume,source=cmsis-6-vcpkg-cache,target=/var/cache/vcpkg \ + --mount type=bind,source="$HOME/.armlm",target="/home/$(id -un)/.armlm" \ + cmsis-6-dev +``` + +Inside a newly created command-line container, initialize it once, activate the +tools, and enter the repository: + +```bash +/home/postCreateCommand.sh +source "$HOME/.vcpkg/vcpkg-init" +pushd /home +vcpkg-shell activate +popd +cd /workspaces/CMSIS_6 +``` + +To inspect the shared cache from the host, run: + +```bash +docker volume inspect cmsis-6-vcpkg-cache +``` + +When a completely clean tool download is required, stop containers using the +volume and remove it with `docker volume rm cmsis-6-vcpkg-cache`. The next +container creation downloads the tools again. + +## Matrix selectors + +Both `build.py` runners use the same selectors: + +| Axis | Option | Common values | +|---|---|---| +| Compiler | `-c`, `--compiler` | `AC6`, `GCC`, `Clang`, `Clang_TI` | +| Core/device | `-d`, `--device` | `CM0`, `CM3`, `CM4`, `CM33S`, `CM55`, `CA53`, `CR52` | +| Optimization | `-o`, `--optimize` | `none`, `balanced`, `size`, `speed` | + +Omitting an axis selects all of its available values. Repeat an option to select +multiple values: + +```bash +-c GCC -c Clang -d CM3 -d CM4 -o none -o speed +``` + +Device selectors accept patterns. Quote patterns to prevent shell expansion; +for example, `-d "CM33*"` selects `CM33`, `CM33S`, and `CM33NS`. +Use `./build.py --help` in either suite to list every supported value. + +## Core LIT tests + +Run commands from `CMSIS/Core/Test`: + +```bash +cd CMSIS/Core/Test +``` + +A quick smoke test using one compiler, core, and optimization level is: + +```bash +./build.py -c GCC -d CM3 -o none lit +``` + +Examples of limited selections: + +```bash +# One compiler across all supported cores and optimization levels +./build.py -c GCC lit + +# Every Cortex-M33 security variant, using one compiler and optimization level +./build.py -c GCC -d "CM33*" -o none lit + +# Two compilers and two optimization levels for one core +./build.py -c GCC -c Clang -d CM4FP -o none -o speed lit + +# A representative selection for a broad, shared Core-M change +./build.py -c GCC -c Clang \ + -d CM0 -d CM4FP -d CM33S -d CM55 \ + -o none lit +``` + +Run one LIT source test directly when diagnosing a focused change: + +```bash +lit -D toolchain=GCC -D device=CM3 -D optimize=none -a src/apsr.c +``` + +The complete matrix for the toolchains installed by the dev container is: + +```bash +./build.py --silent -c AC6 -c GCC -c Clang lit +``` + +The runner writes timestamped `*.xunit` reports in `CMSIS/Core/Test`. + +## CoreValidation build and runtime tests + +CoreValidation requires the generic Cortex Device Family Pack. Install or +update it once inside the container: + +```bash +git clone https://github.com/ARM-software/Cortex_DFP.git "$HOME/Cortex_DFP" +cpackget add "$HOME/Cortex_DFP/ARM.Cortex_DFP.pdsc" +``` + +For an existing clone, update it before re-registering the PDSC: + +```bash +git -C "$HOME/Cortex_DFP" pull --ff-only +cpackget add "$HOME/Cortex_DFP/ARM.Cortex_DFP.pdsc" +``` + +Run commands from `CMSIS/CoreValidation/Project`: + +```bash +cd CMSIS/CoreValidation/Project +``` + +Build and run a single configuration: + +```bash +./build.py -c GCC -d CM3 -o none build run +``` + +The `CA9QEMU` target runs on QEMU's `vexpress-a9` machine instead of an FVP: + +```bash +./build.py -c GCC -d CA9QEMU -o none build run +``` + +QEMU TCG does not model dirty cache-line data, so this target excludes +`TC_CAL1Cache_InvalidateDCacheAll`; the remaining Cortex-A9 tests run normally. + +Examples of limited selections: + +```bash +# Build only; do not start an FVP +./build.py -c GCC -d CM3 -o none build + +# Run all Cortex-M33 security variants +./build.py -c GCC -d "CM33*" -o none build run + +# Test two compilers and two optimization levels on one core +./build.py -c GCC -c Clang -d CM4 -o none -o speed build run + +# A representative runtime selection for a broad, shared Core-M change +./build.py -c GCC \ + -d CM0 -d CM4 -d CM33S -d CM55 \ + -o none build run +``` + +Run the complete Cortex-M matrix supported by the configured dev-container +toolchains with: + +```bash +./build.py --verbose \ + -c AC6 -c GCC -c Clang \ + -d "CM*" build run +``` + +CoreValidation writes build archives and timestamped JUnit reports below +`CMSIS/CoreValidation/Project/build`. + +## Choosing a useful subset + +Use the smallest selection that covers the changed behavior, then expand if a +failure or the scope of the diff warrants it: + +- Start with `GCC`, the directly affected core, and `none` optimization. +- Add `Clang` for compiler abstractions, intrinsics, inline assembly, or shared + headers. +- Add `AC6` for Arm Compiler-specific branches when the license permits it. +- Add `speed` and `size` for changes that can alter generated instructions, + inlining, barriers, volatile access, or undefined-behavior exposure. +- Include `S` and `NS` variants for TrustZone, partition, or secure gateway + changes. +- For a shared Core-M change, sample an early baseline core, an FPU/DSP core, a + TrustZone core, and a recent M-profile core; the examples above use `CM0`, + `CM4FP`/`CM4`, `CM33S`, and `CM55`. +- Add an A-profile or R-profile device when the changed files affect that + profile. Do not infer A/R coverage from a Core-M-only run. +- LIT is normally sufficient for compile-time API and instruction-selection + changes. Add CoreValidation for runtime semantics, startup and system code, + exceptions, interrupts, security state, or integration changes. + +Compiler and FVP coverage can depend on the Arm license mounted at +`$HOME/.armlm`. Report unavailable licensed features as blocked configurations, +separately from source or test failures. Some combinations are also filtered by +the runners when a toolchain does not support them. + +After a run, inspect `git status --short`. CMSIS-Toolbox `--update-rte` may +create generated RTE files on a bind-mounted workspace. Preserve all +pre-existing changes and remove only files created by the current run.