Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@
* SPDX-License-Identifier: MIT
**************************************************************************/

// Some portions generated by Claude Code (Opus 5).


/**************************************************************************/
/**************************************************************************/
Expand Down Expand Up @@ -105,7 +107,7 @@ _tx_initialize_low_level:

/* Configure SysTick. */
LDR r0, =0xE000E000 // Build address of NVIC registers
MOV r1, #0 // Build value for SysTick reset
MOVS r1, #0 // Build value for SysTick reset
STR r1, [r0, #0x10] // Reset SysTick Control
STR r1, [r0, #0x18] // Reset SysTick Counter Value
LDR r1, =SYSTICK_CYCLES
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@
* SPDX-License-Identifier: MIT
**************************************************************************/

// Some portions generated by Claude Code (Opus 5).


/**************************************************************************/
/**************************************************************************/
Expand Down Expand Up @@ -69,7 +71,14 @@ _tx_thread_context_restore:
/* Call the ISR exit function to indicate an ISR is complete. */
PUSH {r0, lr} // Save return address
BL _tx_execution_isr_exit // Call the ISR exit function
POP {r0, lr} // Recover return address
POP {r0, r1} // Recover r0 and the return address
MOV lr, r1 // This core cannot POP into LR: the
// 16-bit Thumb POP takes r0-r7 and
// pc only. MOV to a high register
// is permitted, so restore LR from
// a scratch register. r1 is free --
// the BL above may clobber r0-r3,
// which is why r0 is saved at all.
#endif

BX lr
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@
* SPDX-License-Identifier: MIT
**************************************************************************/

// Some portions generated by Claude Code (Opus 5).


/**************************************************************************/
/**************************************************************************/
Expand Down Expand Up @@ -69,7 +71,14 @@ _tx_thread_context_save:
/* Call the ISR enter function to indicate an ISR is starting. */
PUSH {r0, lr} // Save return address
BL _tx_execution_isr_enter // Call the ISR enter function
POP {r0, lr} // Recover return address
POP {r0, r1} // Recover r0 and the return address
MOV lr, r1 // This core cannot POP into LR: the
// 16-bit Thumb POP takes r0-r7 and
// pc only. MOV to a high register
// is permitted, so restore LR from
// a scratch register. r1 is free --
// the BL above may clobber r0-r3,
// which is why r0 is saved at all.
#endif

BX lr
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@
* SPDX-License-Identifier: MIT
**************************************************************************/

// Some portions generated by Claude Code (Opus 5).


/**************************************************************************/
/**************************************************************************/
Expand Down Expand Up @@ -67,7 +69,7 @@ _tx_thread_secure_stack_initialize:
SVC 3
CPSID i // Disable interrupts
#else
MOV r0, #0xFF // Feature not enabled
MOVS r0, #0xFF // Feature not enabled
#endif
BX lr
.end
14 changes: 13 additions & 1 deletion scripts/check_clang.sh
Original file line number Diff line number Diff line change
Expand Up @@ -211,7 +211,13 @@ say ""
say "== Assembly sources of every Arm gnu port =="

total=0
for dir in ports/*/gnu/src ports_smp/*/gnu/src ports_module/*/gnu/src; do
# The module ports keep their assembly in module_manager/src, not src. This
# glob read ports_module/*/gnu/src until 26 Aug 2026; that directory does not
# exist, the [ -d ] guard below skipped it in silence, and 116 files across
# nine Arm module ports were assembled by no check with either compiler. The
# count went from 724 to 840 when the path was corrected, and three of the new
# files did not assemble.
for dir in ports/*/gnu/src ports_smp/*/gnu/src ports_module/*/gnu/module_manager/src; do
[ -d "$dir" ] || continue
core="$(echo "$dir" | cut -d/ -f2)"
spec="${PORT_TARGET[$core]:-}"
Expand Down Expand Up @@ -246,7 +252,13 @@ say "== Assembly behind feature macros =="
for macro in $FEATURE_MACROS; do
macro_total=0
macro_bad=0
# The module ports are named here for the same reason as in the stage
# above: they were absent from this list until 26 Aug 2026 and so read as
# covered. Adding them found the Cortex-M23 module manager carrying the
# very POP {r0, lr} this comment describes, six months after the same fix
# landed in its non-module sibling.
for src in $(grep -rl "$macro" ports/*/gnu/src/*.S ports_smp/*/gnu/src/*.S \
ports_module/*/gnu/module_manager/src/*.S \
2>/dev/null | sort); do
core="$(echo "$src" | cut -d/ -f2)"
spec="${PORT_TARGET[$core]:-}"
Expand Down
56 changes: 55 additions & 1 deletion scripts/check_ports.sh
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,11 @@
# body in ports/cortex_m4/ac6/inc/tx_port.h, which placed statements
# outside any function. See issue 569.
#
# 4. Lowercase .s under a gnu tree. GAS preprocesses .S and not .s, so a
# .s file's #ifdef blocks are assembled whichever way the macro is set.
# Twenty-nine files were in that state, including one non-module SMP
# kernel port, and only one of them failed to assemble.
#
# The last section reports, without failing, on port families that have no copy
# script and so cannot be checked for reproducibility.
#
Expand Down Expand Up @@ -197,7 +202,56 @@ done < <(find ports ports_arch ports_module ports_smp -name "*.h" -type f \
[ "$orphans" -eq 0 ] && say " ok: no port header carries code at file scope"

# --------------------------------------------------------------------------
# 4. Report only: families with no copy script.
# 4. GNU assembly that uses the preprocessor must be named .S, not .s.
# --------------------------------------------------------------------------
# GAS runs the C preprocessor on .S and not on .s. In a .s file every line
# beginning with # is just a comment, so nothing fails and nothing is
# substituted: a #define constant reaches the assembler as an undefined
# symbol, an #ifdef block is assembled whatever the macro says, and an
# #if/#else pair emits *both* branches. The port silently ignores its own
# feature macros.
#
# Measured 26 Aug 2026, when a corrected glob in check_clang.sh first offered
# the module ports to a compiler. Twenty-nine files were affected, and the
# damage was not only cosmetic:
#
# ports_smp/cortex_a7_smp/gnu/src/tx_thread_smp_unprotect.s -- the only .s
# in a directory of twenty-one .S -- wrote the caller's LR into the
# protection structure on every unprotect, a store guarded by
# TX_MPCORE_DEBUG_ENABLE, and returned through both BX lr and MOV pc, lr.
#
# ports_module/cortex_m33/.../tx_thread_stack_build.s emitted both arms of
# an #ifdef TX_SINGLE_MODE_SECURE, so the second LR value overwrote the
# first and the secure build got the non-secure one.
#
# ports_module/cortex_a7/.../tx_thread_schedule.s did fail to assemble, on
# GCC 14.3 as well as on LLVM, because #define SYS_MODE was never expanded.
# That is the only one of the twenty-nine any compiler complained about.
#
# Only the gnu trees are checked. The IAR, Arm Compiler 5 and Keil assemblers
# preprocess .s themselves, so the same combination is correct there, and
# around three hundred files in this repository depend on it.
say ""
say "== GNU assembly using the preprocessor is named .S =="

lowercase=0
while IFS= read -r f; do
first="$(grep -nE '^[ \t]*#[ \t]*(define|include|if|ifdef|ifndef|else|elif|endif|undef)\b' \
"$f" | head -1)"
if [ -n "$first" ]; then
fail "$f: preprocessor directive in a .s file, which GAS does not preprocess"
echo " line $first"
echo " Rename the file to .S. Check the callers first: a build script"
echo " that already names it .S is the usual sign of how this happened."
lowercase=$((lowercase + 1))
fi
done < <(find ports ports_arch ports_module ports_smp -name "*.s" -type f \
-path "*/gnu/*" 2>/dev/null | sort)

[ "$lowercase" -eq 0 ] && say " ok: no .s file under a gnu tree uses the preprocessor"

# --------------------------------------------------------------------------
# 5. Report only: families with no copy script.
# --------------------------------------------------------------------------
# These are maintained by hand, so a fix applied to one toolchain can silently
# miss the others. Nothing here fails the run; it is a prompt to look.
Expand Down