summaryrefslogtreecommitdiff
path: root/ports_arch/ARMv8-A
diff options
context:
space:
mode:
Diffstat (limited to 'ports_arch/ARMv8-A')
-rw-r--r--ports_arch/ARMv8-A/threadx/common/inc/tx_port.h2
-rw-r--r--ports_arch/ARMv8-A/threadx/ports/ac6/example_build/sample_threadx/sample_threadx.launch7
-rw-r--r--ports_arch/ARMv8-A/threadx/ports/gnu/CMakeLists.txt30
-rwxr-xr-xports_arch/ARMv8-A/threadx/ports/gnu/example_build/build_threadx.sh87
-rwxr-xr-xports_arch/ARMv8-A/threadx/ports/gnu/example_build/build_threadx_sample.sh109
-rw-r--r--ports_arch/ARMv8-A/threadx/ports/gnu/example_build/readme.md39
-rw-r--r--ports_arch/ARMv8-A/threadx/ports/gnu/example_build/sample_threadx/sample_threadx.launch7
-rw-r--r--ports_arch/ARMv8-A/threadx/ports/gnu/example_build/sample_threadx/semihost_stub.S43
-rw-r--r--ports_arch/ARMv8-A/threadx/ports/gnu/src/tx_initialize_low_level.S2
-rw-r--r--ports_arch/ARMv8-A/threadx_smp/common/inc/tx_port.h2
-rw-r--r--ports_arch/ARMv8-A/threadx_smp/common/src/tx_thread_smp_time_get.S3
-rw-r--r--ports_arch/ARMv8-A/threadx_smp/ports/ac6/example_build/sample_threadx/sample_threadx.launch18
-rw-r--r--ports_arch/ARMv8-A/threadx_smp/ports/gnu/CMakeLists.txt39
-rw-r--r--ports_arch/ARMv8-A/threadx_smp/ports/gnu/example_build/sample_threadx/sample_threadx.launch19
-rw-r--r--ports_arch/ARMv8-A/update.ps133
-rwxr-xr-xports_arch/ARMv8-A/update.sh191
16 files changed, 573 insertions, 58 deletions
diff --git a/ports_arch/ARMv8-A/threadx/common/inc/tx_port.h b/ports_arch/ARMv8-A/threadx/common/inc/tx_port.h
index 4487de47..691fedd8 100644
--- a/ports_arch/ARMv8-A/threadx/common/inc/tx_port.h
+++ b/ports_arch/ARMv8-A/threadx/common/inc/tx_port.h
@@ -361,7 +361,7 @@ VOID tx_thread_fp_disable(VOID);
#ifdef TX_THREAD_INIT
CHAR _tx_version_id[] =
- "(c) 2024 Microsoft Corp. (c) 2026-present Eclipse ThreadX contributors. * ThreadX ARMv8-A Version 6.5.1.202602a *";
+ "(c) 2024 Microsoft Corp. (c) 2026-present Eclipse ThreadX contributors. * ThreadX ARMv8-A Version 6.5.2.202603 *";
#else
extern CHAR _tx_version_id[];
#endif
diff --git a/ports_arch/ARMv8-A/threadx/ports/ac6/example_build/sample_threadx/sample_threadx.launch b/ports_arch/ARMv8-A/threadx/ports/ac6/example_build/sample_threadx/sample_threadx.launch
index 4aff966d..39d30548 100644
--- a/ports_arch/ARMv8-A/threadx/ports/ac6/example_build/sample_threadx/sample_threadx.launch
+++ b/ports_arch/ARMv8-A/threadx/ports/ac6/example_build/sample_threadx/sample_threadx.launch
@@ -181,7 +181,7 @@
<booleanAttribute key="VFS_ENABLED" value="true"/>
<stringAttribute key="VFS_LOCAL_DIR" value="${workspace_loc}"/>
<stringAttribute key="VFS_REMOTE_MOUNT" value="/writeable"/>
- <stringAttribute key="breakpoints" value="&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot;?&gt;&#10;&lt;breakpoints order=&quot;ALPHA&quot;&gt;&#10;&#9;&lt;breakpoint ignorecount=&quot;0&quot; threadenabled=&quot;no&quot; core_list=&quot;&quot; continue=&quot;no&quot; verboseBreakpoints=&quot;yes&quot; kind=&quot;SOURCEPOSITION&quot;&gt;&#10;&#9;&#9;&lt;master_location index=&quot;0&quot; enabled=&quot;true&quot; version=&quot;2&quot; address=&quot;EL3:0x00000000800088D0&quot; debugFile=&quot;C:/Users/andrejm/work/git/AzureRTOS/threadx_andrejm_armv8a/ports/cortex_a35/ac6/example_build/sample_threadx/sample_threadx.c&quot; hostFile=&quot;C:\Users\andrejm\work\git\AzureRTOS\threadx_andrejm_armv8a\ports\cortex_a35\ac6\example_build\sample_threadx\sample_threadx.c&quot; line=&quot;212&quot; function=&quot;thread_0_entry&quot;/&gt;&#10;&#9;&#9;&lt;location index=&quot;0&quot; enabled=&quot;true&quot; version=&quot;2&quot; address=&quot;EL3:0x00000000800088D0&quot; debugFile=&quot;C:/Users/andrejm/work/git/AzureRTOS/threadx_andrejm_armv8a/ports/cortex_a35/ac6/example_build/sample_threadx/sample_threadx.c&quot; hostFile=&quot;C:\Users\andrejm\work\git\AzureRTOS\threadx_andrejm_armv8a\ports\cortex_a35\ac6\example_build\sample_threadx\sample_threadx.c&quot; line=&quot;212&quot; function=&quot;thread_0_entry&quot;/&gt;&#10;&#9;&#9;&lt;location index=&quot;1&quot; enabled=&quot;true&quot; version=&quot;2&quot; address=&quot;EL1N:0x00000000800088D0&quot; debugFile=&quot;C:/Users/andrejm/work/git/AzureRTOS/threadx_andrejm_armv8a/ports/cortex_a35/ac6/example_build/sample_threadx/sample_threadx.c&quot; hostFile=&quot;C:\Users\andrejm\work\git\AzureRTOS\threadx_andrejm_armv8a\ports\cortex_a35\ac6\example_build\sample_threadx\sample_threadx.c&quot; line=&quot;212&quot; function=&quot;thread_0_entry&quot;/&gt;&#10;&#9;&lt;/breakpoint&gt;&#10;&lt;/breakpoints&gt;&#10;"/>
+ <stringAttribute key="breakpoints" value="&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot;?&gt;&#10;&lt;breakpoints order=&quot;ALPHA&quot;&gt;&#10;&lt;/breakpoints&gt;&#10;"/>
<listAttribute key="com.arm.debug.views.common.AddressTracker.debugger.view.DisassemblyView.addresses">
<listEntry value="&lt;Next Instruction&gt;"/>
<listEntry value=""/>
@@ -311,15 +311,10 @@
<stringAttribute key="os_extension_id" value="com.arm.debug.os.threadx"/>
<booleanAttribute key="runAfterConnect" value="false"/>
<stringAttribute key="runTargetInitializationScript" value="${workspace_loc:/sample_threadx/use_model_semihosting.ds}"/>
- <mapAttribute key="scripts_view_script_links">
- <mapEntry key="C:\Users\andrejm\work\git\AzureRTOS\threadx_andrejm_armv8a\ports\cortex_a35\ac6\example_build\sample_threadx\use_model_semihosting.ds" value=""/>
- <mapEntry key="C:\Users\nisohack\Documents\work\x-ware_libs\threadx\ports\cortex_a35\ac6\example_build\sample_threadx\use_model_semihosting.ds" value=""/>
- </mapAttribute>
<listAttribute key="setup">
<listEntry value="CDB://Scripts/rtsm_launcher.py"/>
<listEntry value="&quot;FVP_Base_Cortex-A35x1&quot;"/>
</listAttribute>
<stringAttribute key="stopAtExpression" value="*$ENTRYPOINT"/>
- <stringAttribute key="substitutePath" value="&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot;?&gt;&#10;&lt;tuplelist&gt;&#10;&#9;&lt;tuple&gt;&#10;&#9;&#9;&lt;ta&gt;C:\temp1702\tx\&lt;/ta&gt;&#10;&#9;&#9;&lt;tb&gt;C:\temp1702\tx\&lt;/tb&gt;&#10;&#9;&lt;/tuple&gt;&#10;&lt;/tuplelist&gt;&#10;"/>
<stringAttribute key="watchpoints" value="&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot;?&gt;&#10;&lt;watchpoints&gt;&#10;&lt;/watchpoints&gt;&#10;"/>
</launchConfiguration>
diff --git a/ports_arch/ARMv8-A/threadx/ports/gnu/CMakeLists.txt b/ports_arch/ARMv8-A/threadx/ports/gnu/CMakeLists.txt
new file mode 100644
index 00000000..972c10f1
--- /dev/null
+++ b/ports_arch/ARMv8-A/threadx/ports/gnu/CMakeLists.txt
@@ -0,0 +1,30 @@
+# Copyright (c) 2026 Eclipse ThreadX contributors
+# SPDX-License-Identifier: MIT
+# Portions of this file were generated with AI assistance.
+#
+# ThreadX port sources for the AArch64 cores, GNU tools.
+# Copied into every AArch64 gnu port by update.sh, so edit it here.
+
+target_sources(${PROJECT_NAME}
+ PRIVATE
+ # {{BEGIN_TARGET_SOURCES}}
+ ${CMAKE_CURRENT_LIST_DIR}/src/tx_initialize_low_level.S
+ ${CMAKE_CURRENT_LIST_DIR}/src/tx_thread_context_restore.S
+ ${CMAKE_CURRENT_LIST_DIR}/src/tx_thread_context_save.S
+ ${CMAKE_CURRENT_LIST_DIR}/src/tx_thread_fp_disable.c
+ ${CMAKE_CURRENT_LIST_DIR}/src/tx_thread_fp_enable.c
+ ${CMAKE_CURRENT_LIST_DIR}/src/tx_thread_interrupt_control.S
+ ${CMAKE_CURRENT_LIST_DIR}/src/tx_thread_interrupt_disable.S
+ ${CMAKE_CURRENT_LIST_DIR}/src/tx_thread_interrupt_restore.S
+ ${CMAKE_CURRENT_LIST_DIR}/src/tx_thread_schedule.S
+ ${CMAKE_CURRENT_LIST_DIR}/src/tx_thread_stack_build.S
+ ${CMAKE_CURRENT_LIST_DIR}/src/tx_thread_system_return.S
+ ${CMAKE_CURRENT_LIST_DIR}/src/tx_timer_interrupt.S
+ # {{END_TARGET_SOURCES}}
+)
+
+target_include_directories(${PROJECT_NAME}
+ SYSTEM
+ PUBLIC
+ ${CMAKE_CURRENT_LIST_DIR}/inc
+)
diff --git a/ports_arch/ARMv8-A/threadx/ports/gnu/example_build/build_threadx.sh b/ports_arch/ARMv8-A/threadx/ports/gnu/example_build/build_threadx.sh
new file mode 100755
index 00000000..b3b2cd36
--- /dev/null
+++ b/ports_arch/ARMv8-A/threadx/ports/gnu/example_build/build_threadx.sh
@@ -0,0 +1,87 @@
+#!/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
+##############################################################################
+
+# Builds the ThreadX library, tx.a, for the AArch64 port this script sits in.
+# The AArch64 examples previously had no build driver at all and could only be
+# built through Arm Development Studio project files.
+#
+# ./build_threadx.sh
+# TOOLCHAIN=atfe ATFE_CLANG=/path/to/clang ./build_threadx.sh
+#
+# The CPU is derived from the directory this script lives in, so one script
+# serves every AArch64 port rather than needing one copy per core.
+
+set -eu
+
+cd "$(dirname "$(realpath "$0")")"
+
+# ports/<core>/gnu/example_build -> up two levels is <core> -> the -mcpu name.
+# The same example tree is copied into the SMP ports, where the core directory
+# carries an _smp suffix and the kernel sources live in common_smp.
+core="$(basename "$(cd ../.. && pwd)")"
+case "${core}" in
+ *_smp) cpu="${core%_smp}"; common="common_smp" ;;
+ *) cpu="${core}"; common="common" ;;
+esac
+cpu="${cpu//_/-}"
+
+: "${TOOLCHAIN:=gnu}"
+case "${TOOLCHAIN}" in
+ gnu)
+ CC="aarch64-none-elf-gcc"
+ AR="aarch64-none-elf-ar"
+ TARGET_FLAGS=""
+ ;;
+ atfe)
+ CC="${ATFE_CLANG:-clang}"
+ case "${CC}" in
+ */*) AR="$(dirname "${CC}")/llvm-ar" ;;
+ *) AR="llvm-ar" ;;
+ esac
+ TARGET_FLAGS="--target=aarch64-none-elf"
+ ;;
+ *)
+ echo "Unknown TOOLCHAIN '${TOOLCHAIN}'; expected gnu or atfe" >&2
+ exit 1
+ ;;
+esac
+
+CFLAGS="-g -mcpu=${cpu} -I../../../../${common}/inc -I../inc"
+
+echo "Building tx.a for ${cpu} with ${TOOLCHAIN}"
+
+rm -f tx.a ./*.o
+
+# Port sources. The SMP ports carry C sources here as well as assembly.
+for src in ../src/*.S ../src/*.c; do
+ [ -f "${src}" ] || continue
+ obj="$(basename "${src}")"
+ "${CC}" ${TARGET_FLAGS} -c ${CFLAGS} "${src}" -o "${obj%.*}.o"
+done
+
+# Common ThreadX sources. tx_misra.c is deliberately excluded: it is only for
+# MISRA builds and has an assembly counterpart in the port.
+for src in ../../../../${common}/src/*.c; do
+ case "$(basename "${src}")" in
+ tx_misra.c) continue ;;
+ esac
+ "${CC}" ${TARGET_FLAGS} -c ${CFLAGS} "${src}" -o "$(basename "${src%.c}").o"
+done
+
+"${AR}" -rcs tx.a ./*.o
+rm -f ./*.o
+
+echo "Done: $(basename "$(pwd)")/tx.a"
diff --git a/ports_arch/ARMv8-A/threadx/ports/gnu/example_build/build_threadx_sample.sh b/ports_arch/ARMv8-A/threadx/ports/gnu/example_build/build_threadx_sample.sh
new file mode 100755
index 00000000..94248a88
--- /dev/null
+++ b/ports_arch/ARMv8-A/threadx/ports/gnu/example_build/build_threadx_sample.sh
@@ -0,0 +1,109 @@
+#!/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
+##############################################################################
+
+# Builds the sample image for the AArch64 port this script sits in. Run
+# build_threadx.sh first, which produces tx.a.
+#
+# ./build_threadx_sample.sh
+# TOOLCHAIN=atfe ATFE_CLANG=/path/to/clang ./build_threadx_sample.sh
+#
+# The sample targets a fixed virtual platform: a GICv3 interrupt controller and
+# an SP804 timer at the Base platform addresses. It is not expected to run on
+# other models or on hardware without changing those addresses.
+
+set -eu
+
+cd "$(dirname "$(realpath "$0")")"
+
+core="$(basename "$(cd ../.. && pwd)")"
+case "${core}" in
+ *_smp) cpu="${core%_smp}"; common="common_smp" ;;
+ *) cpu="${core}"; common="common" ;;
+esac
+cpu="${cpu//_/-}"
+
+: "${TOOLCHAIN:=gnu}"
+case "${TOOLCHAIN}" in
+ gnu)
+ CC="aarch64-none-elf-gcc"
+ TARGET_FLAGS=""
+ # rdimon supplies the semihosting syscalls and, with them, the real
+ # initialise_monitor_handles that startup.S calls.
+ SYSCALL_LIB="--specs=rdimon.specs"
+ SEMIHOST_STUB=""
+ # crti.o defines _init and _fini; crtn.o closes them. The link below
+ # passes -nostartfiles, which is right for a port with its own reset
+ # path but also drops these two, and startup.S calls
+ # __libc_init_array, whose newlib implementation calls _init. Without
+ # them every AArch64 sample failed to link:
+ #
+ # libg.a(libc_a-init.o): in function `__libc_init_array':
+ # undefined reference to `_init'
+ # relocation truncated to fit: R_AARCH64_CALL26 against undefined
+ # symbol `_init'
+ #
+ # crti.o must precede every other .init contribution and crtn.o must
+ # follow all of them, which is why they bracket the object list rather
+ # than sitting with the other flags. The AArch32 scripts need none of
+ # this: they use nosys.specs and never reach __libc_init_array.
+ CRT_BEGIN="$("${CC}" -mcpu="${cpu}" -print-file-name=crti.o)"
+ CRT_END="$("${CC}" -mcpu="${cpu}" -print-file-name=crtn.o)"
+ ;;
+ atfe)
+ CC="${ATFE_CLANG:-clang}"
+ TARGET_FLAGS="--target=aarch64-none-elf"
+ SYSCALL_LIB="-lsemihost"
+ # picolibc has no initialise_monitor_handles, and neither does the
+ # toolchain's semihosting library, so the weak stub stands in for it.
+ SEMIHOST_STUB="sample_threadx/semihost_stub.S"
+ # Deliberately empty. picolibc's __libc_init_array does not call _init,
+ # so these images link today and adding crti.o would change a working
+ # link for no reason.
+ CRT_BEGIN=""
+ CRT_END=""
+ ;;
+ *)
+ echo "Unknown TOOLCHAIN '${TOOLCHAIN}'; expected gnu or atfe" >&2
+ exit 1
+ ;;
+esac
+
+CFLAGS="-g -mcpu=${cpu} -I../../../../${common}/inc -I../inc -Isample_threadx"
+
+echo "Building the sample for ${cpu} with ${TOOLCHAIN}"
+
+objects=""
+for src in sample_threadx/startup.S sample_threadx/vectors.S \
+ sample_threadx/v8_aarch64.S sample_threadx/v8_utils.S \
+ sample_threadx/MP_Mutexes.S ${SEMIHOST_STUB} \
+ sample_threadx/GICv3_gicd.c sample_threadx/GICv3_gicr.c \
+ sample_threadx/sp804_timer.c sample_threadx/timer_interrupts.c \
+ sample_threadx/sample_threadx.c; do
+ [ -n "${src}" ] || continue
+ obj="$(basename "${src}")"
+ obj="${obj%.*}.o"
+ "${CC}" ${TARGET_FLAGS} -c ${CFLAGS} "${src}" -o "${obj}"
+ objects="${objects} ${obj}"
+done
+
+"${CC}" ${TARGET_FLAGS} -g -mcpu="${cpu}" -nostartfiles \
+ -T sample_threadx/sample_threadx.ld ${SYSCALL_LIB} \
+ -o sample_threadx.out -Wl,-Map=sample_threadx.map \
+ ${CRT_BEGIN} ${objects} tx.a ${CRT_END}
+
+rm -f ${objects}
+
+echo "Done: $(basename "$(pwd)")/sample_threadx.out"
diff --git a/ports_arch/ARMv8-A/threadx/ports/gnu/example_build/readme.md b/ports_arch/ARMv8-A/threadx/ports/gnu/example_build/readme.md
new file mode 100644
index 00000000..3c52a7da
--- /dev/null
+++ b/ports_arch/ARMv8-A/threadx/ports/gnu/example_build/readme.md
@@ -0,0 +1,39 @@
+# AArch64 GNU example build
+
+Builds the ThreadX library and a sample image for the AArch64 port this
+directory belongs to.
+
+```sh
+./build_threadx.sh # the ThreadX library, tx.a
+./build_threadx_sample.sh # the sample image, sample_threadx.out
+```
+
+Set `TOOLCHAIN=atfe` to build with Arm Toolchain for Embedded, which is LLVM
+based, instead of the GNU toolchain:
+
+```sh
+TOOLCHAIN=atfe ATFE_CLANG=/path/to/clang ./build_threadx.sh
+TOOLCHAIN=atfe ATFE_CLANG=/path/to/clang ./build_threadx_sample.sh
+```
+
+Both scripts derive the `-mcpu` value and the kernel source directory from the
+port directory they sit in, so one pair of scripts serves every AArch64 port,
+SMP included. Before they existed these examples could only be built through the
+Arm Development Studio project files beside them, which is why the `.cproject`
+and `.launch` files remain.
+
+## What the sample targets
+
+A fixed virtual platform: a GICv3 interrupt controller and an SP804 timer at the
+Base platform addresses, as set up by `startup.S`, `vectors.S` and the GICv3
+sources here. It will not run on a model or board that places those peripherals
+elsewhere without changing the addresses.
+
+## Semihosting
+
+`startup.S` calls `initialise_monitor_handles` to open the standard file handles
+over a debugger connection. The GNU toolchain provides it in libgloss, pulled in
+by `--specs=rdimon.specs`. picolibc, which Arm Toolchain for Embedded ships, has
+no equivalent and neither does its semihosting library, so `semihost_stub.S`
+supplies a weak no-op for that toolchain only. A real definition always wins
+over it.
diff --git a/ports_arch/ARMv8-A/threadx/ports/gnu/example_build/sample_threadx/sample_threadx.launch b/ports_arch/ARMv8-A/threadx/ports/gnu/example_build/sample_threadx/sample_threadx.launch
index 12938fd1..40477c01 100644
--- a/ports_arch/ARMv8-A/threadx/ports/gnu/example_build/sample_threadx/sample_threadx.launch
+++ b/ports_arch/ARMv8-A/threadx/ports/gnu/example_build/sample_threadx/sample_threadx.launch
@@ -184,7 +184,7 @@
<booleanAttribute key="VFS_ENABLED" value="true"/>
<stringAttribute key="VFS_LOCAL_DIR" value="${workspace_loc}"/>
<stringAttribute key="VFS_REMOTE_MOUNT" value="/writeable"/>
- <stringAttribute key="breakpoints" value="&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot;?&gt;&#10;&lt;breakpoints order=&quot;ALPHA&quot;&gt;&#10;&#9;&lt;breakpoint ignorecount=&quot;0&quot; threadenabled=&quot;no&quot; core_list=&quot;&quot; continue=&quot;no&quot; verboseBreakpoints=&quot;yes&quot; kind=&quot;SOURCEPOSITION&quot;&gt;&#10;&#9;&#9;&lt;master_location index=&quot;0&quot; enabled=&quot;true&quot; version=&quot;2&quot; address=&quot;EL3:0x0000000080000800&quot; debugFile=&quot;C:/Users/nisohack/Documents/work/x-ware_libs/threadx/ports/cortex_a35/gnu/example_build/sample_threadx/vectors.S&quot; hostFile=&quot;C:\Users\nisohack\Documents\work\x-ware_libs\threadx\ports\cortex_a35\gnu\example_build\sample_threadx\vectors.S&quot; line=&quot;27&quot;/&gt;&#10;&#9;&#9;&lt;location index=&quot;0&quot; enabled=&quot;true&quot; version=&quot;2&quot; address=&quot;EL3:0x0000000080000800&quot; debugFile=&quot;C:/Users/nisohack/Documents/work/x-ware_libs/threadx/ports/cortex_a35/gnu/example_build/sample_threadx/vectors.S&quot; hostFile=&quot;C:\Users\nisohack\Documents\work\x-ware_libs\threadx\ports\cortex_a35\gnu\example_build\sample_threadx\vectors.S&quot; line=&quot;27&quot;/&gt;&#10;&#9;&#9;&lt;location index=&quot;1&quot; enabled=&quot;true&quot; version=&quot;2&quot; address=&quot;EL1N:0x0000000080000800&quot; debugFile=&quot;C:/Users/nisohack/Documents/work/x-ware_libs/threadx/ports/cortex_a35/gnu/example_build/sample_threadx/vectors.S&quot; hostFile=&quot;C:\Users\nisohack\Documents\work\x-ware_libs\threadx\ports\cortex_a35\gnu\example_build\sample_threadx\vectors.S&quot; line=&quot;27&quot;/&gt;&#10;&#9;&lt;/breakpoint&gt;&#10;&lt;/breakpoints&gt;&#10;"/>
+ <stringAttribute key="breakpoints" value="&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot;?&gt;&#10;&lt;breakpoints order=&quot;ALPHA&quot;&gt;&#10;&lt;/breakpoints&gt;&#10;"/>
<listAttribute key="com.arm.debug.views.common.AddressTracker.debugger.view.DisassemblyView.addresses">
<listEntry value="&lt;Next Instruction&gt;"/>
<listEntry value=""/>
@@ -314,15 +314,10 @@
<stringAttribute key="model_params" value="-C bp.secure_memory=false -C cache_state_modelled=0"/>
<booleanAttribute key="runAfterConnect" value="false"/>
<stringAttribute key="runTargetInitializationScript" value="${workspace_loc:/sample_threadx/use_model_semihosting.ds}"/>
- <mapAttribute key="scripts_view_script_links">
- <mapEntry key="C:\Users\nisohack\Documents\work\x-ware_libs\threadx\ports\cortex_a35\ac6\example_build\sample_threadx\use_model_semihosting.ds" value=""/>
- <mapEntry key="C:\Users\nisohack\Documents\work\x-ware_libs\threadx\ports\cortex_a35\gnu\example_build\sample_threadx\use_model_semihosting.ds" value=""/>
- </mapAttribute>
<listAttribute key="setup">
<listEntry value="CDB://Scripts/rtsm_launcher.py"/>
<listEntry value="&quot;FVP_Base_Cortex-A35x1&quot;"/>
</listAttribute>
<stringAttribute key="stopAtExpression" value="*$ENTRYPOINT"/>
- <stringAttribute key="substitutePath" value="&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot;?&gt;&#10;&lt;tuplelist&gt;&#10;&#9;&lt;tuple&gt;&#10;&#9;&#9;&lt;ta&gt;C:\temp1702\tx\&lt;/ta&gt;&#10;&#9;&#9;&lt;tb&gt;C:\temp1702\tx\&lt;/tb&gt;&#10;&#9;&lt;/tuple&gt;&#10;&lt;/tuplelist&gt;&#10;"/>
<stringAttribute key="watchpoints" value="&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot;?&gt;&#10;&lt;watchpoints&gt;&#10;&lt;/watchpoints&gt;&#10;"/>
</launchConfiguration>
diff --git a/ports_arch/ARMv8-A/threadx/ports/gnu/example_build/sample_threadx/semihost_stub.S b/ports_arch/ARMv8-A/threadx/ports/gnu/example_build/sample_threadx/semihost_stub.S
new file mode 100644
index 00000000..c456875d
--- /dev/null
+++ b/ports_arch/ARMv8-A/threadx/ports/gnu/example_build/sample_threadx/semihost_stub.S
@@ -0,0 +1,43 @@
+/***************************************************************************
+ * 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
+ **************************************************************************/
+
+/**************************************************************************/
+/** */
+/** ThreadX Component */
+/** */
+/** ARMv8-A example semihosting stub */
+/** */
+/**************************************************************************/
+
+/* startup.S calls initialise_monitor_handles to open the standard file handles
+ over a debugger connection. The GNU toolchain provides it in libgloss, which
+ --specs=rdimon.specs pulls in, so this file is linked only for the LLVM
+ toolchain: picolibc has no equivalent, and neither does the toolchain's own
+ semihosting library, so without it the sample does not link at all.
+
+ The definition is weak, so a real one always wins if something provides it.
+ The sample writes nothing to the standard handles, so doing nothing here
+ costs it no output. */
+
+ .text
+ .balign 4
+
+ .weak initialise_monitor_handles
+ .type initialise_monitor_handles, %function
+initialise_monitor_handles:
+ ret
+ .size initialise_monitor_handles, . - initialise_monitor_handles
+
+ .end
diff --git a/ports_arch/ARMv8-A/threadx/ports/gnu/src/tx_initialize_low_level.S b/ports_arch/ARMv8-A/threadx/ports/gnu/src/tx_initialize_low_level.S
index 3025f12b..f86568c5 100644
--- a/ports_arch/ARMv8-A/threadx/ports/gnu/src/tx_initialize_low_level.S
+++ b/ports_arch/ARMv8-A/threadx/ports/gnu/src/tx_initialize_low_level.S
@@ -9,6 +9,7 @@
* SPDX-License-Identifier: MIT
**************************************************************************/
+// Portions of this file were generated with AI assistance.
/**************************************************************************/
/**************************************************************************/
@@ -83,7 +84,6 @@ _tx_initialize_low_level:
LDR x0, =_tx_initialize_unused_memory // Pickup address of unused memory ptr
LDR x1, =__top_of_ram // Pickup unused memory address
- LDR x1, [x1] //
STR x1, [x0] // Store unused memory address
/* Done, return to caller. */
diff --git a/ports_arch/ARMv8-A/threadx_smp/common/inc/tx_port.h b/ports_arch/ARMv8-A/threadx_smp/common/inc/tx_port.h
index e97d78d5..38c86cb2 100644
--- a/ports_arch/ARMv8-A/threadx_smp/common/inc/tx_port.h
+++ b/ports_arch/ARMv8-A/threadx_smp/common/inc/tx_port.h
@@ -411,7 +411,7 @@ VOID tx_thread_fp_disable(VOID);
#ifdef TX_THREAD_INIT
CHAR _tx_version_id[] =
- "(c) 2024 Microsoft Corp. (c) 2026-present Eclipse ThreadX contributors. * ThreadX ARMv8-A-SMP Version 6.5.1.202602a *";
+ "(c) 2024 Microsoft Corp. (c) 2026-present Eclipse ThreadX contributors. * ThreadX ARMv8-A-SMP Version 6.5.2.202603 *";
#else
extern CHAR _tx_version_id[];
#endif
diff --git a/ports_arch/ARMv8-A/threadx_smp/common/src/tx_thread_smp_time_get.S b/ports_arch/ARMv8-A/threadx_smp/common/src/tx_thread_smp_time_get.S
index 335824fb..4bb9f1cb 100644
--- a/ports_arch/ARMv8-A/threadx_smp/common/src/tx_thread_smp_time_get.S
+++ b/ports_arch/ARMv8-A/threadx_smp/common/src/tx_thread_smp_time_get.S
@@ -9,6 +9,7 @@
* SPDX-License-Identifier: MIT
**************************************************************************/
+// Portions of this file were generated with AI assistance.
/**************************************************************************/
/**************************************************************************/
@@ -60,5 +61,5 @@
.global _tx_thread_smp_time_get
.type _tx_thread_smp_time_get, @function
_tx_thread_smp_time_get:
- MOV x0, #0 // FIXME: Get timer
+ MRS x0, CNTPCT_EL0 // Read generic timer physical count
RET
diff --git a/ports_arch/ARMv8-A/threadx_smp/ports/ac6/example_build/sample_threadx/sample_threadx.launch b/ports_arch/ARMv8-A/threadx_smp/ports/ac6/example_build/sample_threadx/sample_threadx.launch
index 5a0bdcf4..639e2f4e 100644
--- a/ports_arch/ARMv8-A/threadx_smp/ports/ac6/example_build/sample_threadx/sample_threadx.launch
+++ b/ports_arch/ARMv8-A/threadx_smp/ports/ac6/example_build/sample_threadx/sample_threadx.launch
@@ -214,17 +214,10 @@
<listEntry value="element formatter"/>
<listEntry value="Hexadecimal"/>
</listAttribute>
- <listAttribute key="TREE_NODE_PROPERTIES:debugger.view.VariableTreeView">
- <listEntry value="NODE CACHE VERSION 1"/>
- <listEntry value="LOCALS:Locals:VALUE:B:/support/broadcom/tx58cortexa53arm/release/threadx/tx/tx_thread_system_suspend.c::_tx_thread_system_suspend::possible_cores"/>
- <listEntry value="1"/>
- <listEntry value="formatter"/>
- <listEntry value="Hexadecimal"/>
- </listAttribute>
<booleanAttribute key="VFS_ENABLED" value="true"/>
<stringAttribute key="VFS_LOCAL_DIR" value="${workspace_loc}"/>
<stringAttribute key="VFS_REMOTE_MOUNT" value="/writeable"/>
- <stringAttribute key="breakpoints" value="&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot;?&gt;&#10;&lt;breakpoints order=&quot;ALPHA&quot;&gt;&#10;&#9;&lt;breakpoint ignorecount=&quot;0&quot; threadenabled=&quot;no&quot; core_list=&quot;&quot; continue=&quot;no&quot; verboseBreakpoints=&quot;yes&quot; kind=&quot;SOURCEPOSITION&quot;&gt;&#10;&#9;&#9;&lt;master_location index=&quot;0&quot; enabled=&quot;true&quot; version=&quot;2&quot; address=&quot;EL3:0x000000008000B64C&quot; debugFile=&quot;C:/Users/andrejm/work/git/AzureRTOS/threadx_andrejm_armv8a/ports_smp/cortex_a35_smp/ac6/example_build/sample_threadx/sample_threadx.c&quot; hostFile=&quot;C:\Users\andrejm\work\git\AzureRTOS\threadx_andrejm_armv8a\ports_smp\cortex_a35_smp\ac6\example_build\sample_threadx\sample_threadx.c&quot; line=&quot;212&quot; function=&quot;thread_0_entry&quot;/&gt;&#10;&#9;&#9;&lt;location index=&quot;0&quot; enabled=&quot;true&quot; version=&quot;2&quot; address=&quot;EL3:0x000000008000B64C&quot; debugFile=&quot;C:/Users/andrejm/work/git/AzureRTOS/threadx_andrejm_armv8a/ports_smp/cortex_a35_smp/ac6/example_build/sample_threadx/sample_threadx.c&quot; hostFile=&quot;C:\Users\andrejm\work\git\AzureRTOS\threadx_andrejm_armv8a\ports_smp\cortex_a35_smp\ac6\example_build\sample_threadx\sample_threadx.c&quot; line=&quot;212&quot; function=&quot;thread_0_entry&quot;/&gt;&#10;&#9;&#9;&lt;location index=&quot;1&quot; enabled=&quot;true&quot; version=&quot;2&quot; address=&quot;EL1N:0x000000008000B64C&quot; debugFile=&quot;C:/Users/andrejm/work/git/AzureRTOS/threadx_andrejm_armv8a/ports_smp/cortex_a35_smp/ac6/example_build/sample_threadx/sample_threadx.c&quot; hostFile=&quot;C:\Users\andrejm\work\git\AzureRTOS\threadx_andrejm_armv8a\ports_smp\cortex_a35_smp\ac6\example_build\sample_threadx\sample_threadx.c&quot; line=&quot;212&quot; function=&quot;thread_0_entry&quot;/&gt;&#10;&#9;&lt;/breakpoint&gt;&#10;&lt;/breakpoints&gt;&#10;"/>
+ <stringAttribute key="breakpoints" value="&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot;?&gt;&#10;&lt;breakpoints order=&quot;ALPHA&quot;&gt;&#10;&lt;/breakpoints&gt;&#10;"/>
<listAttribute key="com.arm.debug.views.common.AddressTracker.debugger.view.DisassemblyView.addresses">
<listEntry value=""/>
<listEntry value="&lt;Next Instruction&gt;"/>
@@ -395,19 +388,10 @@
<stringAttribute key="os_extension_id" value="com.arm.debug.os.threadx"/>
<booleanAttribute key="runAfterConnect" value="false"/>
<stringAttribute key="runTargetInitializationScript" value="${workspace_loc:/sample_threadx/use_model_semihosting.ds}"/>
- <mapAttribute key="scripts_view_script_links">
- <mapEntry key="B:\support\broadcom\a53smp_el1_clean_mar25\sample_threadx\use_model_semihosting.ds" value=""/>
- <mapEntry key="B:\support\broadcom\tx58cortexa53arm\release\threadx\sample_threadx\use_model_semihosting.ds" value=""/>
- <mapEntry key="C:\Users\andrejm\work\git\AzureRTOS\threadx_andrejm_armv8a\ports_smp\cortex_a35_smp\ac6\example_build\sample_threadx\use_model_semihosting.ds" value=""/>
- <mapEntry key="C:\Users\andrejm\work\git\AzureRTOS\threadx_other\ports_smp\cortex_a35_smp\ac6\example_build\sample_threadx\use_model_semihosting.ds" value=""/>
- <mapEntry key="C:\Users\nisohack\Documents\work\x-ware_libs\threadx\ports_smp\cortex_a35_smp\ac6\example_build\sample_threadx\use_model_semihosting.ds" value=""/>
- <mapEntry key="C:\Users\nisohack\Documents\work\x-ware_libs\threadx_github\ports\cortex_a5x_smp\ac6\example_build\sample_threadx\use_model_semihosting.ds" value=""/>
- </mapAttribute>
<listAttribute key="setup">
<listEntry value="CDB://Scripts/rtsm_launcher.py"/>
<listEntry value="&quot;FVP_Base_Cortex-A35x4&quot;"/>
</listAttribute>
<stringAttribute key="stopAtExpression" value="*$ENTRYPOINT"/>
- <stringAttribute key="substitutePath" value="&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot;?&gt;&#10;&lt;tuplelist&gt;&#10;&#9;&lt;tuple&gt;&#10;&#9;&#9;&lt;ta&gt;C:/release/threadx/sample_threadx&lt;/ta&gt;&#10;&#9;&#9;&lt;tb&gt;C:\release\threadx\sample_threadx\&lt;/tb&gt;&#10;&#9;&lt;/tuple&gt;&#10;&#9;&lt;tuple&gt;&#10;&#9;&#9;&lt;ta&gt;C:/release/threadx/tx&lt;/ta&gt;&#10;&#9;&#9;&lt;tb&gt;C:\release\threadx\sample_threadx\&lt;/tb&gt;&#10;&#9;&lt;/tuple&gt;&#10;&lt;/tuplelist&gt;&#10;"/>
<stringAttribute key="watchpoints" value="&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot;?&gt;&#10;&lt;watchpoints&gt;&#10;&lt;/watchpoints&gt;&#10;"/>
</launchConfiguration>
diff --git a/ports_arch/ARMv8-A/threadx_smp/ports/gnu/CMakeLists.txt b/ports_arch/ARMv8-A/threadx_smp/ports/gnu/CMakeLists.txt
new file mode 100644
index 00000000..36f7492b
--- /dev/null
+++ b/ports_arch/ARMv8-A/threadx_smp/ports/gnu/CMakeLists.txt
@@ -0,0 +1,39 @@
+# Copyright (c) 2026 Eclipse ThreadX contributors
+# SPDX-License-Identifier: MIT
+# Portions of this file were generated with AI assistance.
+#
+# ThreadX SMP port sources for the AArch64 cores, GNU tools.
+# Copied into every AArch64 gnu SMP port by update.sh, so edit it here.
+
+target_sources(${PROJECT_NAME}
+ PRIVATE
+ # {{BEGIN_TARGET_SOURCES}}
+ ${CMAKE_CURRENT_LIST_DIR}/src/tx_initialize_low_level.S
+ ${CMAKE_CURRENT_LIST_DIR}/src/tx_thread_context_restore.S
+ ${CMAKE_CURRENT_LIST_DIR}/src/tx_thread_context_save.S
+ ${CMAKE_CURRENT_LIST_DIR}/src/tx_thread_fp_disable.c
+ ${CMAKE_CURRENT_LIST_DIR}/src/tx_thread_fp_enable.c
+ ${CMAKE_CURRENT_LIST_DIR}/src/tx_thread_interrupt_control.S
+ ${CMAKE_CURRENT_LIST_DIR}/src/tx_thread_interrupt_disable.S
+ ${CMAKE_CURRENT_LIST_DIR}/src/tx_thread_interrupt_restore.S
+ ${CMAKE_CURRENT_LIST_DIR}/src/tx_thread_schedule.S
+ ${CMAKE_CURRENT_LIST_DIR}/src/tx_thread_smp_core_get.S
+ ${CMAKE_CURRENT_LIST_DIR}/src/tx_thread_smp_core_preempt.S
+ ${CMAKE_CURRENT_LIST_DIR}/src/tx_thread_smp_current_state_get.S
+ ${CMAKE_CURRENT_LIST_DIR}/src/tx_thread_smp_current_thread_get.S
+ ${CMAKE_CURRENT_LIST_DIR}/src/tx_thread_smp_initialize_wait.S
+ ${CMAKE_CURRENT_LIST_DIR}/src/tx_thread_smp_low_level_initialize.S
+ ${CMAKE_CURRENT_LIST_DIR}/src/tx_thread_smp_protect.S
+ ${CMAKE_CURRENT_LIST_DIR}/src/tx_thread_smp_time_get.S
+ ${CMAKE_CURRENT_LIST_DIR}/src/tx_thread_smp_unprotect.S
+ ${CMAKE_CURRENT_LIST_DIR}/src/tx_thread_stack_build.S
+ ${CMAKE_CURRENT_LIST_DIR}/src/tx_thread_system_return.S
+ ${CMAKE_CURRENT_LIST_DIR}/src/tx_timer_interrupt.S
+ # {{END_TARGET_SOURCES}}
+)
+
+target_include_directories(${PROJECT_NAME}
+ SYSTEM
+ PUBLIC
+ ${CMAKE_CURRENT_LIST_DIR}/inc
+)
diff --git a/ports_arch/ARMv8-A/threadx_smp/ports/gnu/example_build/sample_threadx/sample_threadx.launch b/ports_arch/ARMv8-A/threadx_smp/ports/gnu/example_build/sample_threadx/sample_threadx.launch
index d583631e..d06144eb 100644
--- a/ports_arch/ARMv8-A/threadx_smp/ports/gnu/example_build/sample_threadx/sample_threadx.launch
+++ b/ports_arch/ARMv8-A/threadx_smp/ports/gnu/example_build/sample_threadx/sample_threadx.launch
@@ -239,13 +239,6 @@
<listEntry value="element formatter"/>
<listEntry value="Character"/>
</listAttribute>
- <listAttribute key="TREE_NODE_PROPERTIES:debugger.view.VariableTreeView">
- <listEntry value="NODE CACHE VERSION 1"/>
- <listEntry value="LOCALS:Locals:VALUE:B:/support/broadcom/tx58cortexa53arm/release/threadx/tx/tx_thread_system_suspend.c::_tx_thread_system_suspend::possible_cores"/>
- <listEntry value="1"/>
- <listEntry value="formatter"/>
- <listEntry value="Hexadecimal"/>
- </listAttribute>
<booleanAttribute key="VFS_ENABLED" value="true"/>
<stringAttribute key="VFS_LOCAL_DIR" value="${workspace_loc}"/>
<stringAttribute key="VFS_REMOTE_MOUNT" value="/writeable"/>
@@ -424,22 +417,10 @@
<stringAttribute key="os_extension_id" value="com.arm.debug.os.threadx"/>
<booleanAttribute key="runAfterConnect" value="false"/>
<stringAttribute key="runTargetInitializationScript" value="${workspace_loc:/sample_threadx/use_model_semihosting.ds}"/>
- <mapAttribute key="scripts_view_script_links">
- <mapEntry key="B:\support\broadcom\a53smp_el1_clean_mar25\sample_threadx\use_model_semihosting.ds" value=""/>
- <mapEntry key="B:\support\broadcom\tx58cortexa53arm\release\threadx\sample_threadx\use_model_semihosting.ds" value=""/>
- <mapEntry key="C:\Users\andrejm\work\git\AzureRTOS\threadx_other\ports_smp\cortex_a35_smp\gnu\example_build\sample_threadx\use_model_semihosting.ds" value=""/>
- <mapEntry key="C:\Users\nisohack\Documents\work\x-ware_libs\threadx\ports_smp\cortex_a35_smp\gnu\example_build\sample_threadx\use_model_semihosting.ds" value=""/>
- <mapEntry key="C:\Users\nisohack\Documents\work\x-ware_libs\threadx_github\ports\cortex_a5x_smp\gnu\example_build\common\use_model_semihosting.ds" value=""/>
- <mapEntry key="D:\Documents\work\get_threadx-smp_cortex-a53_gnu_working\threadx_arm\threadx\common\use_model_semihosting.ds" value=""/>
- <mapEntry key="D:\Documents\work\get_threadx-smp_cortex-a53_gnu_working\threadx_arm\threadx\sample_threadx\use_model_semihosting.ds" value=""/>
- <mapEntry key="D:\Documents\work\get_threadx-smp_cortex-a53_gnu_working\threadx_official_workspace_no_sevice_packs\threadx\common\use_model_semihosting.ds" value=""/>
- <mapEntry key="D:\Documents\work\get_threadx-smp_cortex-a53_gnu_working\threadx_official_workspaces_no_sevice_packs\threadx\common\use_model_semihosting.ds" value=""/>
- </mapAttribute>
<listAttribute key="setup">
<listEntry value="CDB://Scripts/rtsm_launcher.py"/>
<listEntry value="&quot;FVP_Base_Cortex-A35x4&quot;"/>
</listAttribute>
<stringAttribute key="stopAtExpression" value="*$ENTRYPOINT"/>
- <stringAttribute key="substitutePath" value="&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot;?&gt;&#10;&lt;tuplelist&gt;&#10;&#9;&lt;tuple&gt;&#10;&#9;&#9;&lt;ta&gt;/tmp/dgboter/bbs/dsggnu-vm-1-x86_64--mingw32-i686/buildbot/mingw32-i686--aarch64-elf/build/src/newlib-cygwin/libgloss/aarch64/&lt;/ta&gt;&#10;&#9;&#9;&lt;tb&gt;D:\Documents\work\toolchains\newlib-cygwin\libgloss\aarch64\&lt;/tb&gt;&#10;&#9;&lt;/tuple&gt;&#10;&#9;&lt;tuple&gt;&#10;&#9;&#9;&lt;ta&gt;C:/release/threadx/sample_threadx&lt;/ta&gt;&#10;&#9;&#9;&lt;tb&gt;C:\release\threadx\sample_threadx\&lt;/tb&gt;&#10;&#9;&lt;/tuple&gt;&#10;&#9;&lt;tuple&gt;&#10;&#9;&#9;&lt;ta&gt;C:/release/threadx/tx&lt;/ta&gt;&#10;&#9;&#9;&lt;tb&gt;C:\release\threadx\sample_threadx\&lt;/tb&gt;&#10;&#9;&lt;/tuple&gt;&#10;&lt;/tuplelist&gt;&#10;"/>
<stringAttribute key="watchpoints" value="&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot;?&gt;&#10;&lt;watchpoints&gt;&#10;&lt;/watchpoints&gt;&#10;"/>
</launchConfiguration>
diff --git a/ports_arch/ARMv8-A/update.ps1 b/ports_arch/ARMv8-A/update.ps1
index 0663b603..98ba818d 100644
--- a/ports_arch/ARMv8-A/update.ps1
+++ b/ports_arch/ARMv8-A/update.ps1
@@ -77,7 +77,13 @@ Write-Verbose ("Copy regression test: $CopyRegressionTest")
Write-Verbose ("Patch files: $PatchFiles")
Write-Verbose ("LogDir: $LogDir")
-$cores = @("cortex_a35", "cortex_a53", "cortex_a55", "cortex_a57", "cortex_a65", "cortex_a65ae", "cortex_a72", "cortex_a73", "cortex_a75", "cortex_a76", "cortex_a76ae", "cortex_a77")
+$cores = @("cortex_a34", "cortex_a35", "cortex_a53", "cortex_a55", "cortex_a57", "cortex_a65", "cortex_a65ae", "cortex_a72", "cortex_a73", "cortex_a75", "cortex_a76", "cortex_a76ae", "cortex_a77")
+
+# Cortex-A78 ships as an SMP port only: ports_smp\cortex_a78_smp exists but
+# ports\cortex_a78 does not. Listing it separately keeps the generator from
+# creating a ThreadX port that the tree has never had.
+$cores_smp_only = @("cortex_a78")
+
$compilers = @("ac6", "gnu")
$patches = (
('example_build\sample_threadx\.cproject', (
@@ -88,17 +94,26 @@ $patches = (
(('value="cortex-a35"'), ('value="cortex-$($core_short_lower)"')),
(('Cortex-A35.AArch64.ARMv8.Neon.Crypto'), ('Cortex-$($core_short_upper).AArch64.ARMv8.Neon.Crypto'))
)),
+ # The base_a35x<n> entries are the config database taxonomy id, which is
+ # spelt in lower case in the launch files. They used to read base_A35x<n>,
+ # which -creplace never matched, leaving every port pointing at the A35
+ # platform. The Cortex-A35x<n> SMP entries are the activity name the SMP
+ # launch files use in place of "Debug Cortex-A35"; matching the " SMP"
+ # suffix keeps them from also rewriting the FVP model name.
('example_build\sample_threadx\sample_threadx.launch', (
('Debug Cortex-A35', 'Debug Cortex-$($core_short_upper)'),
('Base_A35x1', 'Base_$($core_short_upper)x1'),
- ('base_A35x1', 'base_$($core_short_lower)x1'),
+ ('base_a35x1', 'base_$($core_short_lower)x1'),
('FVP_Base_Cortex-A35x1', 'FVP_Base_Cortex-$($core_short_upper)x1'),
+ ('Cortex-A35x1 SMP', 'Cortex-$($core_short_upper)x1 SMP'),
('Base_A35x2', 'Base_$($core_short_upper)x2'),
- ('base_A35x2', 'base_$($core_short_lower)x2'),
+ ('base_a35x2', 'base_$($core_short_lower)x2'),
('FVP_Base_Cortex-A35x2', 'FVP_Base_Cortex-$($core_short_upper)x2'),
+ ('Cortex-A35x2 SMP', 'Cortex-$($core_short_upper)x2 SMP'),
('Base_A35x4', 'Base_$($core_short_upper)x4'),
- ('base_A35x4', 'base_$($core_short_lower)x4'),
- ('FVP_Base_Cortex-A35x4', 'FVP_Base_Cortex-$($core_short_upper)x4')
+ ('base_a35x4', 'base_$($core_short_lower)x4'),
+ ('FVP_Base_Cortex-A35x4', 'FVP_Base_Cortex-$($core_short_upper)x4'),
+ ('Cortex-A35x4 SMP', 'Cortex-$($core_short_upper)x4 SMP')
))
)
@@ -119,7 +134,13 @@ Function Copy-FilesVerbose {
}
ForEach ($PortSet in $PortSets) {
- ForEach ($core in $cores) {
+ If ($PortSet -eq "tx_smp") {
+ $PortSetCores = $cores + $cores_smp_only
+ } Else {
+ $PortSetCores = $cores
+ }
+
+ ForEach ($core in $PortSetCores) {
Switch ($PortSet) {
"tx" { $core_directory = "..\..\ports\" + $core }
"tx_smp" { $core_directory = "..\..\ports_smp\" + $core + "_smp" }
diff --git a/ports_arch/ARMv8-A/update.sh b/ports_arch/ARMv8-A/update.sh
new file mode 100755
index 00000000..4084d33f
--- /dev/null
+++ b/ports_arch/ARMv8-A/update.sh
@@ -0,0 +1,191 @@
+#!/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
+##############################################################################
+
+# Update the ARMv8-A ports from the generic ARMv8-A port, generating ports and
+# examples from the common files. This is a port of update.ps1 beside it, which
+# needs PowerShell and so could only be run on Windows. The two are kept
+# equivalent: same cores, same compilers, same copy sets and the same patches.
+#
+# To update the ThreadX ports for the source tree:
+# ./update.sh --port-sets tx --copy-common-files --copy-port-files \
+# --copy-example --patch-files
+#
+# To update the ThreadX ports for the test tree:
+# ./update.sh --port-sets tx --copy-common-files --copy-port-files \
+# --copy-example --copy-validation-test --copy-regression-test \
+# --patch-files
+#
+# --copy-example, --copy-validation-test and --copy-regression-test are
+# accepted and ignored, exactly as in update.ps1, where they are declared as
+# parameters but never consulted. They are kept so that both scripts take the
+# same command line.
+
+set -eu
+
+cd "$(dirname "$(realpath "$0")")"
+
+cores="cortex_a34 cortex_a35 cortex_a53 cortex_a55 cortex_a57 cortex_a65 cortex_a65ae \
+ cortex_a72 cortex_a73 cortex_a75 cortex_a76 cortex_a76ae cortex_a77"
+
+# Cortex-A78 ships as an SMP port only: ports_smp/cortex_a78_smp exists but
+# ports/cortex_a78 does not. Listing it separately keeps the generator from
+# creating a ThreadX port that the tree has never had.
+cores_smp_only="cortex_a78"
+
+compilers="ac6 gnu"
+
+port_sets=""
+copy_common_files=0
+copy_port_files=0
+patch_files=0
+
+usage() {
+ sed -n '22,35p' "$0"
+ exit "${1:-1}"
+}
+
+while [ "$#" -gt 0 ]; do
+ case "$1" in
+ --port-sets)
+ [ "$#" -ge 2 ] || { echo "Error: --port-sets needs a value" >&2; exit 1; }
+ port_sets="$(printf '%s' "$2" | tr ',' ' ')"
+ shift 2
+ ;;
+ --copy-common-files) copy_common_files=1; shift ;;
+ --copy-port-files) copy_port_files=1; shift ;;
+ --patch-files) patch_files=1; shift ;;
+ # Accepted and ignored, as in update.ps1.
+ --copy-example|--copy-validation-test|--copy-regression-test) shift ;;
+ -h|--help) usage 0 ;;
+ *) echo "Error: unknown option '$1'" >&2; usage ;;
+ esac
+done
+
+if [ -z "${port_sets}" ]; then
+ echo "Error: --port-sets is required" >&2
+ usage
+fi
+
+for port_set in ${port_sets}; do
+ case "${port_set}" in
+ tx|tx_smp|txm|txm_smp) ;;
+ *) echo "Error: invalid port set '${port_set}'" >&2; exit 1 ;;
+ esac
+done
+
+echo "Update the ARMv8-A ports"
+
+# Copy the contents of a directory over a destination, creating what is missing
+# and overwriting what is not. This mirrors Copy-Item -Recurse -Force, which
+# merges into the destination rather than replacing it.
+copy_files() {
+ source_dir="$1"
+ destination_directory="$2"
+
+ if [ -d "${source_dir}" ]; then
+ cp -Rf "${source_dir}/." "${destination_directory}/"
+ fi
+}
+
+# Replace every occurrence of a literal string in a file, leaving the file
+# alone when it does not exist. Only the files named in the patch list below
+# are ever touched.
+patch_file() {
+ path="$1"
+ original="$2"
+ substitute="$3"
+
+ [ -f "${path}" ] || return 0
+
+ original_escaped="$(printf '%s' "${original}" | sed -e 's/[][\.*^$/&]/\\&/g')"
+ substitute_escaped="$(printf '%s' "${substitute}" | sed -e 's/[\/&]/\\&/g')"
+ sed -i "s/${original_escaped}/${substitute_escaped}/g" "${path}"
+}
+
+for port_set in ${port_sets}; do
+ case "${port_set}" in
+ tx_smp) port_set_cores="${cores} ${cores_smp_only}" ;;
+ *) port_set_cores="${cores}" ;;
+ esac
+
+ for core in ${port_set_cores}; do
+ case "${port_set}" in
+ tx) core_directory="../../ports/${core}" ;;
+ tx_smp) core_directory="../../ports_smp/${core}_smp" ;;
+ txm) core_directory="../../ports_module/${core}" ;;
+ txm_smp) core_directory="../../ports_module_smp/${core}_smp" ;;
+ esac
+
+ core_short="${core#cortex_}"
+ core_short_lower="$(printf '%s' "${core_short}" | tr '[:upper:]' '[:lower:]')"
+ core_short_upper="$(printf '%s' "${core_short}" | tr '[:lower:]' '[:upper:]')"
+
+ for compiler in ${compilers}; do
+ destination_directory="${core_directory}/${compiler}"
+ mkdir -p "${destination_directory}"
+
+ if [ "${copy_common_files}" -eq 1 ]; then
+ copy_files "threadx/common" "${destination_directory}"
+ fi
+
+ if [ "${copy_port_files}" -eq 1 ]; then
+ copy_files "threadx/ports/${compiler}" "${destination_directory}"
+ fi
+
+ if [ "${port_set}" = "tx_smp" ]; then
+ if [ "${copy_common_files}" -eq 1 ]; then
+ copy_files "threadx_smp/common" "${destination_directory}"
+ fi
+ if [ "${copy_port_files}" -eq 1 ]; then
+ copy_files "threadx_smp/ports/${compiler}" "${destination_directory}"
+ fi
+ fi
+
+ if [ "${patch_files}" -eq 1 ]; then
+ neon='Cortex-A35.AArch64.ARMv8.Neon.Crypto'
+
+ sample_cproject="${destination_directory}/example_build/sample_threadx/.cproject"
+ patch_file "${sample_cproject}" 'value="cortex-a35"' "value=\"cortex-${core_short_lower}\""
+ patch_file "${sample_cproject}" "${neon}" "Cortex-${core_short_upper}.AArch64.ARMv8.Neon.Crypto"
+
+ tx_cproject="${destination_directory}/example_build/tx/.cproject"
+ patch_file "${tx_cproject}" 'value="cortex-a35"' "value=\"cortex-${core_short_lower}\""
+ patch_file "${tx_cproject}" "${neon}" "Cortex-${core_short_upper}.AArch64.ARMv8.Neon.Crypto"
+
+ launch="${destination_directory}/example_build/sample_threadx/sample_threadx.launch"
+ patch_file "${launch}" 'Debug Cortex-A35' "Debug Cortex-${core_short_upper}"
+ for count in 1 2 4; do
+ patch_file "${launch}" "Base_A35x${count}" "Base_${core_short_upper}x${count}"
+ # The config database taxonomy id is spelt in lower case in
+ # the launch files, so the search string must be too. It
+ # used to read base_A35x, which matched nothing and left
+ # every port pointing at the A35 platform. The ARMv7-A
+ # generator gets this right, which is why its ports carry a
+ # per-core ve_cortex_a<n>x1 id.
+ patch_file "${launch}" "base_a35x${count}" "base_${core_short_lower}x${count}"
+ patch_file "${launch}" "FVP_Base_Cortex-A35x${count}" "FVP_Base_Cortex-${core_short_upper}x${count}"
+ # The SMP launch files name the activity "Cortex-A35x4 SMP"
+ # rather than "Debug Cortex-A35", so the rule above does not
+ # reach them. Match the " SMP" suffix so this cannot also
+ # rewrite the FVP model name handled on the line above.
+ patch_file "${launch}" "Cortex-A35x${count} SMP" "Cortex-${core_short_upper}x${count} SMP"
+ done
+ fi
+ done
+ done
+done
+
+echo "Done."