diff --git a/ports/cortex_r5/ac5/inc/tx_port.h b/ports/cortex_r5/ac5/inc/tx_port.h index 3fa52578..d1c69fba 100644 --- a/ports/cortex_r5/ac5/inc/tx_port.h +++ b/ports/cortex_r5/ac5/inc/tx_port.h @@ -9,6 +9,8 @@ * SPDX-License-Identifier: MIT **************************************************************************/ +// Some portions generated by Copilot (Opus 5). + /**************************************************************************/ /**************************************************************************/ @@ -183,7 +185,16 @@ typedef unsigned short USHORT; #define TX_THREAD_EXTENSION_0 #define TX_THREAD_EXTENSION_1 -#define TX_THREAD_EXTENSION_2 + +/* TX_THREAD_EXTENSION_2 carries the per-thread VFP enable flag that the lazy + floating-point save and restore in tx_thread_schedule, tx_thread_system_return + and tx_thread_context_restore reads and writes as [thread, #144]. Without it + a TX_ENABLE_VFP_SUPPORT build has no such member and those accesses land on + tx_thread_filex_ptr instead. Defined unconditionally, matching the Armv7-A + ports: the offset is hard-coded in assembly, so a conditional member would + move every following field and be correct in only one configuration. */ + +#define TX_THREAD_EXTENSION_2 ULONG tx_thread_vfp_enable; #define TX_THREAD_EXTENSION_3 diff --git a/ports/cortex_r5/ac5/src/tx_port_offset_check.c b/ports/cortex_r5/ac5/src/tx_port_offset_check.c new file mode 100644 index 00000000..11eaa253 --- /dev/null +++ b/ports/cortex_r5/ac5/src/tx_port_offset_check.c @@ -0,0 +1,87 @@ +/*************************************************************************** + * 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 Copilot (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 + **************************************************************************/ + +/**************************************************************************/ +/**************************************************************************/ +/** */ +/** ThreadX Component */ +/** */ +/** Port Specific */ +/** */ +/**************************************************************************/ +/**************************************************************************/ + +/**************************************************************************/ +/* */ +/* PORT SPECIFIC C INFORMATION RELEASE */ +/* */ +/* tx_port_offset_check.c Cortex-R5/AC5 */ +/* */ +/* DESCRIPTION */ +/* */ +/* Compile-time verification of the TX_THREAD structure offsets that */ +/* this port's assembly reaches by hard-coded displacement. The file */ +/* emits no code; it exists purely so that a layout change becomes a */ +/* build failure. */ +/* */ +/* Why this is needed: tx_thread_schedule.s, */ +/* tx_thread_system_return.s and tx_thread_context_restore.s read and */ +/* write the per-thread VFP enable flag as [thread, #144]. Nothing in */ +/* the toolchain connects that literal to the C structure, so adding a */ +/* member, enabling an option that adds one, or reordering the port */ +/* extensions would silently retarget those accesses at an unrelated */ +/* field -- corrupting thread state in a way that is extremely hard to */ +/* diagnose from the symptom. The offset was measured at 144 for the */ +/* default build and is asserted here. */ +/* */ +/* NOTE: this port has no CMake build of its own, so this file takes */ +/* effect only in builds that compile everything under src/. It is */ +/* still worthwhile: it emits no code, costs nothing, and protects every */ +/* build that does pick it up. */ +/* */ +/* A negative array dimension is used rather than _Static_assert */ +/* because this project targets C99, where _Static_assert does not */ +/* exist. If an assertion below fails, the compiler reports a negative */ +/* or zero-sized array for the named typedef. */ +/* */ +/**************************************************************************/ + +#include "tx_api.h" +#include + +/* Offset of the VFP enable flag as encoded in this port's assembly. + Overridable only so that the assertion itself can be tested. */ + +#ifndef TX_PORT_VFP_ENABLE_OFFSET +#define TX_PORT_VFP_ENABLE_OFFSET 144 +#endif + +typedef char +tx_port_assert_vfp_enable_offset_is_144[ + (offsetof(TX_THREAD, tx_thread_vfp_enable) == TX_PORT_VFP_ENABLE_OFFSET) + ? 1 : -1]; + +/* The stack pointer is read as [thread, #8] by tx_thread_schedule.S and + written by tx_thread_system_return.s, and the run counter as + [thread, #4]. Assert those too, since they are on the context-switch + critical path. */ + +typedef char +tx_port_assert_stack_ptr_offset_is_8[ + (offsetof(TX_THREAD, tx_thread_stack_ptr) == 8) ? 1 : -1]; + +typedef char +tx_port_assert_run_count_offset_is_4[ + (offsetof(TX_THREAD, tx_thread_run_count) == 4) ? 1 : -1];