#!/bin/bash ############################################################################## # Copyright (c) 2026 Eclipse ThreadX contributors # # This program and the accompanying materials are made available under the # terms of the MIT License which is available at # https://opensource.org/licenses/MIT. # # AI Disclosure: This file was largely AI-generated by Claude Code (Opus 5). # The AI-generated portions may be considered public domain (CC0-1.0) # and not subject to the project's licence. The human contributor has # reviewed and verified that the code is correct. # # SPDX-License-Identifier: MIT and CC0-1.0 ############################################################################## # Runs the Cortex-A7 module range check against a live MMU. # # The host test for that check stands a simulated page map behind the port's # CP15 primitive, so it never executes an address translation. An encoding that # named the wrong operation, or a PAR fault bit read the wrong way round, would # pass it. This check builds a bare-metal image that turns the MMU on and drives # the real check through the real translations, then runs it under an emulator. # # scripts/check_module_mmu_a7.sh # # Environment: # CROSS_CC arm-none-eabi C compiler; defaults to arm-none-eabi-gcc. # QEMU Arm system emulator; defaults to qemu-system-arm. # # Exit status is 0 when the image runs and every expectation holds, 1 when an # expectation fails, and 0 with a notice when the tools are absent, so that a # machine without a cross toolchain does not fail the build. set -u CC="${CROSS_CC:-arm-none-eabi-gcc}" QEMU_BIN="${QEMU:-qemu-system-arm}" ROOT="$(cd "$(dirname "$0")/.." && pwd)" SRC="$ROOT/test/tx/module_manager/threadx_module_manager_cortex_a7_mmu_test.c" PORT="$ROOT/ports_module/cortex_a7/gnu/module_manager/src/txm_module_manager_inside_data_check.c" for tool in "$CC" "$QEMU_BIN"; do if ! command -v "$tool" >/dev/null 2>&1 && [ ! -x "$tool" ]; then echo "Skipping: $tool not found." echo " Needs an arm-none-eabi toolchain and qemu-system-arm." exit 0 fi done # The port supplies the two architecture primitives from its register setup # file, which cannot be compiled here because it also builds the module page # tables. They are provided by the image itself, copied from that file, so what # runs is the same instruction sequence the port issues. work="$(mktemp -d)" trap 'rm -rf "$work"' EXIT cat > "$work/primitives.c" <<'PRIMITIVES' #define TX_SOURCE_CODE #include "tx_api.h" #include "txm_module.h" UINT _txm_module_manager_address_probe(ULONG address, UINT write_request) { ULONG translation; if (write_request == ((UINT) TXM_MODULE_MANAGER_ACCESS_WRITE)) { __asm volatile ("MCR p15, 0, %0, c7, c8, 3" : : "r"(address) : ); } else { __asm volatile ("MCR p15, 0, %0, c7, c8, 2" : : "r"(address) : ); } __asm volatile ("ISB"); __asm volatile ("MRC p15, 0, %0, c7, c4, 0" : "=r"(translation) : : ); if (translation & TXM_ADDRESS_TRANSLATION_FAULT_BIT) { return(TX_FALSE); } return(TX_TRUE); } ULONG _txm_module_manager_current_asid_get(VOID) { ULONG contextidr; __asm volatile ("MRC p15, 0, %0, c13, c0, 1" : "=r"(contextidr) : : ); return(contextidr & TXM_CONTEXTIDR_ASID_MASK); } PRIMITIVES "$CC" -mcpu=cortex-a7 -marm -O1 -std=gnu99 -Wall -Wextra -Werror \ --specs=rdimon.specs \ -I"$ROOT/ports_module/cortex_a7/gnu/inc" \ -I"$ROOT/common/inc" \ -I"$ROOT/common_modules/inc" \ -I"$ROOT/common_modules/module_manager/inc" \ -o "$work/mmu_test.elf" "$SRC" "$PORT" "$work/primitives.c" || { echo "FAIL: the Cortex-A7 MMU test image did not build." exit 1 } output="$("$QEMU_BIN" -M realview-pb-a8 -cpu cortex-a7 -m 128 -nographic \ -semihosting -kernel "$work/mmu_test.elf" 2>/dev/null)" status=$? echo "$output" if [ $status -ne 0 ] || ! echo "$output" | grep -q "SUCCESS!"; then echo "FAIL: the Cortex-A7 MMU test did not report success." exit 1 fi exit 0