Added the missing VFP enable field to the Cortex-R5/AC5 thread control block, which VFP builds were writing over the FileX pointer (#715)

The Cortex-R5/AC5 port defines TX_THREAD_EXTENSION_2 as empty while its
assembly reads and writes the per-thread VFP enable flag at [thread, #144].
With TX_ENABLE_VFP_SUPPORT that offset lands on tx_thread_filex_ptr, so
tx_thread_vfp_enable corrupted the FileX pointer and lazy save/restore
tested an unrelated value.

Defined TX_THREAD_EXTENSION_2 as ULONG tx_thread_vfp_enable, matching the
Armv7-A ports and the Cortex-R4/R5 GNU and AC6 ports fixed earlier, and
added tx_port_offset_check.c so a future layout change breaks the build
instead of silently retargeting the accesses. The offset was measured at
144 for this port and asserted.

Fixes #382

Assisted-by: Copilot (Opus 5) <noreply@github.com>
This commit is contained in:
Frédéric Desbiens
2026-09-09 17:17:37 -04:00
committed by GitHub
parent a8c84593dd
commit 7f6e496233
2 changed files with 99 additions and 1 deletions
+12 -1
View File
@@ -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
@@ -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 <stddef.h>
/* 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];