summaryrefslogtreecommitdiff
path: root/ports_smp
diff options
context:
space:
mode:
Diffstat (limited to 'ports_smp')
-rw-r--r--ports_smp/arc_hs_smp/metaware/inc/tx_port.h2
-rw-r--r--ports_smp/arc_hs_smp/metaware/src/tx_thread_context_save.s23
-rw-r--r--ports_smp/cortex_a34_smp/ac6/example_build/sample_threadx/.cproject2
-rw-r--r--ports_smp/cortex_a34_smp/ac6/example_build/sample_threadx/sample_threadx.launch100
-rw-r--r--ports_smp/cortex_a34_smp/ac6/example_build/tx/.cproject34
-rw-r--r--ports_smp/cortex_a34_smp/ac6/inc/tx_port.h2
-rw-r--r--ports_smp/cortex_a34_smp/ac6/src/tx_thread_context_restore.S7
-rw-r--r--ports_smp/cortex_a34_smp/ac6/src/tx_thread_context_save.S6
-rw-r--r--ports_smp/cortex_a34_smp/ac6/src/tx_thread_interrupt_control.S6
-rw-r--r--ports_smp/cortex_a34_smp/ac6/src/tx_thread_interrupt_disable.S6
-rw-r--r--ports_smp/cortex_a34_smp/ac6/src/tx_thread_interrupt_restore.S8
-rw-r--r--ports_smp/cortex_a34_smp/ac6/src/tx_thread_schedule.S8
-rw-r--r--ports_smp/cortex_a34_smp/ac6/src/tx_thread_smp_core_get.S8
-rw-r--r--ports_smp/cortex_a34_smp/ac6/src/tx_thread_smp_core_preempt.S9
-rw-r--r--ports_smp/cortex_a34_smp/ac6/src/tx_thread_smp_current_state_get.S8
-rw-r--r--ports_smp/cortex_a34_smp/ac6/src/tx_thread_smp_current_thread_get.S8
-rw-r--r--ports_smp/cortex_a34_smp/ac6/src/tx_thread_smp_initialize_wait.S8
-rw-r--r--ports_smp/cortex_a34_smp/ac6/src/tx_thread_smp_low_level_initialize.S8
-rw-r--r--ports_smp/cortex_a34_smp/ac6/src/tx_thread_smp_protect.S8
-rw-r--r--ports_smp/cortex_a34_smp/ac6/src/tx_thread_smp_time_get.S11
-rw-r--r--ports_smp/cortex_a34_smp/ac6/src/tx_thread_smp_unprotect.S8
-rw-r--r--ports_smp/cortex_a34_smp/ac6/src/tx_thread_stack_build.S6
-rw-r--r--ports_smp/cortex_a34_smp/ac6/src/tx_thread_system_return.S7
-rw-r--r--ports_smp/cortex_a34_smp/ac6/src/tx_timer_interrupt.S6
-rw-r--r--ports_smp/cortex_a34_smp/gnu/CMakeLists.txt39
-rwxr-xr-xports_smp/cortex_a34_smp/gnu/example_build/build_threadx.sh87
-rwxr-xr-xports_smp/cortex_a34_smp/gnu/example_build/build_threadx_sample.sh109
-rw-r--r--ports_smp/cortex_a34_smp/gnu/example_build/readme.md39
-rw-r--r--ports_smp/cortex_a34_smp/gnu/example_build/sample_threadx/sample_threadx.launch27
-rw-r--r--ports_smp/cortex_a34_smp/gnu/example_build/sample_threadx/semihost_stub.S43
-rw-r--r--ports_smp/cortex_a34_smp/gnu/example_build/tx/.cproject8
-rw-r--r--ports_smp/cortex_a34_smp/gnu/inc/tx_port.h2
-rw-r--r--ports_smp/cortex_a34_smp/gnu/src/tx_initialize_low_level.S6
-rw-r--r--ports_smp/cortex_a34_smp/gnu/src/tx_thread_context_restore.S7
-rw-r--r--ports_smp/cortex_a34_smp/gnu/src/tx_thread_context_save.S6
-rw-r--r--ports_smp/cortex_a34_smp/gnu/src/tx_thread_interrupt_control.S6
-rw-r--r--ports_smp/cortex_a34_smp/gnu/src/tx_thread_interrupt_disable.S6
-rw-r--r--ports_smp/cortex_a34_smp/gnu/src/tx_thread_interrupt_restore.S8
-rw-r--r--ports_smp/cortex_a34_smp/gnu/src/tx_thread_schedule.S8
-rw-r--r--ports_smp/cortex_a34_smp/gnu/src/tx_thread_smp_core_get.S8
-rw-r--r--ports_smp/cortex_a34_smp/gnu/src/tx_thread_smp_core_preempt.S9
-rw-r--r--ports_smp/cortex_a34_smp/gnu/src/tx_thread_smp_current_state_get.S8
-rw-r--r--ports_smp/cortex_a34_smp/gnu/src/tx_thread_smp_current_thread_get.S8
-rw-r--r--ports_smp/cortex_a34_smp/gnu/src/tx_thread_smp_initialize_wait.S8
-rw-r--r--ports_smp/cortex_a34_smp/gnu/src/tx_thread_smp_low_level_initialize.S8
-rw-r--r--ports_smp/cortex_a34_smp/gnu/src/tx_thread_smp_protect.S8
-rw-r--r--ports_smp/cortex_a34_smp/gnu/src/tx_thread_smp_time_get.S11
-rw-r--r--ports_smp/cortex_a34_smp/gnu/src/tx_thread_smp_unprotect.S8
-rw-r--r--ports_smp/cortex_a34_smp/gnu/src/tx_thread_stack_build.S6
-rw-r--r--ports_smp/cortex_a34_smp/gnu/src/tx_thread_system_return.S7
-rw-r--r--ports_smp/cortex_a34_smp/gnu/src/tx_timer_interrupt.S6
-rw-r--r--ports_smp/cortex_a35_smp/ac6/example_build/sample_threadx/sample_threadx.launch18
-rw-r--r--ports_smp/cortex_a35_smp/ac6/inc/tx_port.h2
-rw-r--r--ports_smp/cortex_a35_smp/ac6/src/tx_thread_smp_time_get.S3
-rw-r--r--ports_smp/cortex_a35_smp/gnu/CMakeLists.txt39
-rwxr-xr-xports_smp/cortex_a35_smp/gnu/example_build/build_threadx.sh87
-rwxr-xr-xports_smp/cortex_a35_smp/gnu/example_build/build_threadx_sample.sh109
-rw-r--r--ports_smp/cortex_a35_smp/gnu/example_build/readme.md39
-rw-r--r--ports_smp/cortex_a35_smp/gnu/example_build/sample_threadx/sample_threadx.launch19
-rw-r--r--ports_smp/cortex_a35_smp/gnu/example_build/sample_threadx/semihost_stub.S43
-rw-r--r--ports_smp/cortex_a35_smp/gnu/inc/tx_port.h2
-rw-r--r--ports_smp/cortex_a35_smp/gnu/src/tx_thread_smp_time_get.S3
-rw-r--r--ports_smp/cortex_a53_smp/ac6/example_build/sample_threadx/sample_threadx.launch22
-rw-r--r--ports_smp/cortex_a53_smp/ac6/inc/tx_port.h2
-rw-r--r--ports_smp/cortex_a53_smp/ac6/src/tx_thread_smp_time_get.S3
-rw-r--r--ports_smp/cortex_a53_smp/gnu/CMakeLists.txt39
-rwxr-xr-xports_smp/cortex_a53_smp/gnu/example_build/build_threadx.sh87
-rwxr-xr-xports_smp/cortex_a53_smp/gnu/example_build/build_threadx_sample.sh109
-rw-r--r--ports_smp/cortex_a53_smp/gnu/example_build/readme.md39
-rw-r--r--ports_smp/cortex_a53_smp/gnu/example_build/sample_threadx/sample_threadx.launch23
-rw-r--r--ports_smp/cortex_a53_smp/gnu/example_build/sample_threadx/semihost_stub.S43
-rw-r--r--ports_smp/cortex_a53_smp/gnu/inc/tx_port.h2
-rw-r--r--ports_smp/cortex_a53_smp/gnu/src/tx_thread_smp_time_get.S3
-rw-r--r--ports_smp/cortex_a55_smp/ac6/example_build/sample_threadx/sample_threadx.launch22
-rw-r--r--ports_smp/cortex_a55_smp/ac6/inc/tx_port.h2
-rw-r--r--ports_smp/cortex_a55_smp/ac6/src/tx_thread_smp_time_get.S3
-rw-r--r--ports_smp/cortex_a55_smp/gnu/CMakeLists.txt39
-rwxr-xr-xports_smp/cortex_a55_smp/gnu/example_build/build_threadx.sh87
-rwxr-xr-xports_smp/cortex_a55_smp/gnu/example_build/build_threadx_sample.sh109
-rw-r--r--ports_smp/cortex_a55_smp/gnu/example_build/readme.md39
-rw-r--r--ports_smp/cortex_a55_smp/gnu/example_build/sample_threadx/sample_threadx.launch23
-rw-r--r--ports_smp/cortex_a55_smp/gnu/example_build/sample_threadx/semihost_stub.S43
-rw-r--r--ports_smp/cortex_a55_smp/gnu/inc/tx_port.h2
-rw-r--r--ports_smp/cortex_a55_smp/gnu/src/tx_thread_smp_time_get.S3
-rw-r--r--ports_smp/cortex_a57_smp/ac6/example_build/sample_threadx/sample_threadx.launch22
-rw-r--r--ports_smp/cortex_a57_smp/ac6/inc/tx_port.h2
-rw-r--r--ports_smp/cortex_a57_smp/ac6/src/tx_thread_smp_time_get.S3
-rw-r--r--ports_smp/cortex_a57_smp/gnu/CMakeLists.txt39
-rwxr-xr-xports_smp/cortex_a57_smp/gnu/example_build/build_threadx.sh87
-rwxr-xr-xports_smp/cortex_a57_smp/gnu/example_build/build_threadx_sample.sh109
-rw-r--r--ports_smp/cortex_a57_smp/gnu/example_build/readme.md39
-rw-r--r--ports_smp/cortex_a57_smp/gnu/example_build/sample_threadx/sample_threadx.launch23
-rw-r--r--ports_smp/cortex_a57_smp/gnu/example_build/sample_threadx/semihost_stub.S43
-rw-r--r--ports_smp/cortex_a57_smp/gnu/inc/tx_port.h2
-rw-r--r--ports_smp/cortex_a57_smp/gnu/src/tx_thread_smp_time_get.S3
-rw-r--r--ports_smp/cortex_a5_smp/ac5/inc/tx_port.h2
-rw-r--r--ports_smp/cortex_a5_smp/ac5/src/tx_thread_context_restore.s80
-rw-r--r--ports_smp/cortex_a5_smp/ac5/src/tx_thread_context_save.s12
-rw-r--r--ports_smp/cortex_a5_smp/ac5/src/tx_thread_schedule.s4
-rw-r--r--ports_smp/cortex_a5_smp/ac5/src/tx_thread_smp_protect.s292
-rw-r--r--ports_smp/cortex_a5_smp/ac5/src/tx_thread_smp_protection_wait_list_macros.h314
-rw-r--r--ports_smp/cortex_a5_smp/ac5/src/tx_thread_smp_time_get.s5
-rw-r--r--ports_smp/cortex_a5_smp/ac5/src/tx_thread_smp_unprotect.s7
-rw-r--r--ports_smp/cortex_a5_smp/ac5/src/tx_thread_system_return.s7
-rw-r--r--ports_smp/cortex_a5_smp/ac5/src/tx_thread_vectored_context_save.s12
-rw-r--r--ports_smp/cortex_a5_smp/gnu/CMakeLists.txt38
-rwxr-xr-xports_smp/cortex_a5_smp/gnu/example_build/build_threadx.sh295
-rwxr-xr-xports_smp/cortex_a5_smp/gnu/example_build/build_threadx_sample.sh56
-rw-r--r--ports_smp/cortex_a5_smp/gnu/example_build/crt0.S101
-rw-r--r--ports_smp/cortex_a5_smp/gnu/example_build/tx_initialize_low_level.S (renamed from ports_smp/cortex_a5_smp/gnu/example_build/tx_initialize_low_level.s)0
-rw-r--r--ports_smp/cortex_a5_smp/gnu/inc/tx_port.h2
-rw-r--r--ports_smp/cortex_a5_smp/gnu/src/tx_thread_context_restore.S80
-rw-r--r--ports_smp/cortex_a5_smp/gnu/src/tx_thread_context_save.S12
-rw-r--r--ports_smp/cortex_a5_smp/gnu/src/tx_thread_schedule.S4
-rw-r--r--ports_smp/cortex_a5_smp/gnu/src/tx_thread_smp_protect.S292
-rw-r--r--ports_smp/cortex_a5_smp/gnu/src/tx_thread_smp_protection_wait_list_macros.h309
-rw-r--r--ports_smp/cortex_a5_smp/gnu/src/tx_thread_smp_time_get.S5
-rw-r--r--ports_smp/cortex_a5_smp/gnu/src/tx_thread_smp_unprotect.S7
-rw-r--r--ports_smp/cortex_a5_smp/gnu/src/tx_thread_system_return.S7
-rw-r--r--ports_smp/cortex_a5_smp/gnu/src/tx_thread_vectored_context_save.S12
-rw-r--r--ports_smp/cortex_a5x_smp/ac6/example_build/sample_threadx/sample_threadx.launch14
-rw-r--r--ports_smp/cortex_a5x_smp/ac6/example_build/sample_threadx/startup_AArch64-FVP_Base_AEMv8A.launch13
-rw-r--r--ports_smp/cortex_a5x_smp/ac6/inc/tx_port.h2
-rw-r--r--ports_smp/cortex_a5x_smp/ac6/src/tx_thread_smp_time_get.S3
-rw-r--r--ports_smp/cortex_a5x_smp/gnu/CMakeLists.txt38
-rw-r--r--ports_smp/cortex_a5x_smp/gnu/example_build/sample_threadx/sample_threadx.launch18
-rw-r--r--ports_smp/cortex_a5x_smp/gnu/inc/tx_port.h2
-rw-r--r--ports_smp/cortex_a5x_smp/gnu/src/tx_thread_smp_time_get.S3
-rw-r--r--ports_smp/cortex_a5x_smp/green/inc/tx_port.h2
-rw-r--r--ports_smp/cortex_a5x_smp/green/src/tx_thread_smp_time_get.a644
-rw-r--r--ports_smp/cortex_a5x_smp/iar/inc/tx_port.h2
-rw-r--r--ports_smp/cortex_a5x_smp/iar/src/tx_thread_smp_time_get.S3
-rw-r--r--ports_smp/cortex_a65_smp/ac6/example_build/sample_threadx/sample_threadx.launch22
-rw-r--r--ports_smp/cortex_a65_smp/ac6/inc/tx_port.h2
-rw-r--r--ports_smp/cortex_a65_smp/ac6/src/tx_thread_smp_time_get.S3
-rw-r--r--ports_smp/cortex_a65_smp/gnu/CMakeLists.txt39
-rwxr-xr-xports_smp/cortex_a65_smp/gnu/example_build/build_threadx.sh87
-rwxr-xr-xports_smp/cortex_a65_smp/gnu/example_build/build_threadx_sample.sh109
-rw-r--r--ports_smp/cortex_a65_smp/gnu/example_build/readme.md39
-rw-r--r--ports_smp/cortex_a65_smp/gnu/example_build/sample_threadx/sample_threadx.launch23
-rw-r--r--ports_smp/cortex_a65_smp/gnu/example_build/sample_threadx/semihost_stub.S43
-rw-r--r--ports_smp/cortex_a65_smp/gnu/inc/tx_port.h2
-rw-r--r--ports_smp/cortex_a65_smp/gnu/src/tx_thread_smp_time_get.S3
-rw-r--r--ports_smp/cortex_a65ae_smp/ac6/example_build/sample_threadx/sample_threadx.launch22
-rw-r--r--ports_smp/cortex_a65ae_smp/ac6/inc/tx_port.h2
-rw-r--r--ports_smp/cortex_a65ae_smp/ac6/src/tx_thread_smp_time_get.S3
-rw-r--r--ports_smp/cortex_a65ae_smp/gnu/CMakeLists.txt39
-rwxr-xr-xports_smp/cortex_a65ae_smp/gnu/example_build/build_threadx.sh87
-rwxr-xr-xports_smp/cortex_a65ae_smp/gnu/example_build/build_threadx_sample.sh109
-rw-r--r--ports_smp/cortex_a65ae_smp/gnu/example_build/readme.md39
-rw-r--r--ports_smp/cortex_a65ae_smp/gnu/example_build/sample_threadx/sample_threadx.launch23
-rw-r--r--ports_smp/cortex_a65ae_smp/gnu/example_build/sample_threadx/semihost_stub.S43
-rw-r--r--ports_smp/cortex_a65ae_smp/gnu/inc/tx_port.h2
-rw-r--r--ports_smp/cortex_a65ae_smp/gnu/src/tx_thread_smp_time_get.S3
-rw-r--r--ports_smp/cortex_a72_smp/ac6/example_build/sample_threadx/sample_threadx.launch22
-rw-r--r--ports_smp/cortex_a72_smp/ac6/inc/tx_port.h2
-rw-r--r--ports_smp/cortex_a72_smp/ac6/src/tx_thread_smp_time_get.S3
-rw-r--r--ports_smp/cortex_a72_smp/gnu/CMakeLists.txt39
-rwxr-xr-xports_smp/cortex_a72_smp/gnu/example_build/build_threadx.sh87
-rwxr-xr-xports_smp/cortex_a72_smp/gnu/example_build/build_threadx_sample.sh109
-rw-r--r--ports_smp/cortex_a72_smp/gnu/example_build/readme.md39
-rw-r--r--ports_smp/cortex_a72_smp/gnu/example_build/sample_threadx/sample_threadx.launch23
-rw-r--r--ports_smp/cortex_a72_smp/gnu/example_build/sample_threadx/semihost_stub.S43
-rw-r--r--ports_smp/cortex_a72_smp/gnu/inc/tx_port.h2
-rw-r--r--ports_smp/cortex_a72_smp/gnu/src/tx_thread_smp_time_get.S3
-rw-r--r--ports_smp/cortex_a73_smp/ac6/example_build/sample_threadx/sample_threadx.launch22
-rw-r--r--ports_smp/cortex_a73_smp/ac6/inc/tx_port.h2
-rw-r--r--ports_smp/cortex_a73_smp/ac6/src/tx_thread_smp_time_get.S3
-rw-r--r--ports_smp/cortex_a73_smp/gnu/CMakeLists.txt39
-rwxr-xr-xports_smp/cortex_a73_smp/gnu/example_build/build_threadx.sh87
-rwxr-xr-xports_smp/cortex_a73_smp/gnu/example_build/build_threadx_sample.sh109
-rw-r--r--ports_smp/cortex_a73_smp/gnu/example_build/readme.md39
-rw-r--r--ports_smp/cortex_a73_smp/gnu/example_build/sample_threadx/sample_threadx.launch23
-rw-r--r--ports_smp/cortex_a73_smp/gnu/example_build/sample_threadx/semihost_stub.S43
-rw-r--r--ports_smp/cortex_a73_smp/gnu/inc/tx_port.h2
-rw-r--r--ports_smp/cortex_a73_smp/gnu/src/tx_thread_smp_time_get.S3
-rw-r--r--ports_smp/cortex_a75_smp/ac6/example_build/sample_threadx/sample_threadx.launch22
-rw-r--r--ports_smp/cortex_a75_smp/ac6/inc/tx_port.h2
-rw-r--r--ports_smp/cortex_a75_smp/ac6/src/tx_thread_smp_time_get.S3
-rw-r--r--ports_smp/cortex_a75_smp/gnu/CMakeLists.txt39
-rwxr-xr-xports_smp/cortex_a75_smp/gnu/example_build/build_threadx.sh87
-rwxr-xr-xports_smp/cortex_a75_smp/gnu/example_build/build_threadx_sample.sh109
-rw-r--r--ports_smp/cortex_a75_smp/gnu/example_build/readme.md39
-rw-r--r--ports_smp/cortex_a75_smp/gnu/example_build/sample_threadx/sample_threadx.launch23
-rw-r--r--ports_smp/cortex_a75_smp/gnu/example_build/sample_threadx/semihost_stub.S43
-rw-r--r--ports_smp/cortex_a75_smp/gnu/inc/tx_port.h4
-rw-r--r--ports_smp/cortex_a75_smp/gnu/src/tx_thread_smp_time_get.S3
-rw-r--r--ports_smp/cortex_a76_smp/ac6/example_build/sample_threadx/sample_threadx.launch22
-rw-r--r--ports_smp/cortex_a76_smp/ac6/inc/tx_port.h2
-rw-r--r--ports_smp/cortex_a76_smp/ac6/src/tx_thread_smp_time_get.S3
-rw-r--r--ports_smp/cortex_a76_smp/gnu/CMakeLists.txt39
-rwxr-xr-xports_smp/cortex_a76_smp/gnu/example_build/build_threadx.sh87
-rwxr-xr-xports_smp/cortex_a76_smp/gnu/example_build/build_threadx_sample.sh109
-rw-r--r--ports_smp/cortex_a76_smp/gnu/example_build/readme.md39
-rw-r--r--ports_smp/cortex_a76_smp/gnu/example_build/sample_threadx/sample_threadx.launch23
-rw-r--r--ports_smp/cortex_a76_smp/gnu/example_build/sample_threadx/semihost_stub.S43
-rw-r--r--ports_smp/cortex_a76_smp/gnu/inc/tx_port.h2
-rw-r--r--ports_smp/cortex_a76_smp/gnu/src/tx_thread_smp_time_get.S3
-rw-r--r--ports_smp/cortex_a76ae_smp/ac6/example_build/sample_threadx/sample_threadx.launch22
-rw-r--r--ports_smp/cortex_a76ae_smp/ac6/inc/tx_port.h2
-rw-r--r--ports_smp/cortex_a76ae_smp/ac6/src/tx_thread_smp_time_get.S3
-rw-r--r--ports_smp/cortex_a76ae_smp/gnu/CMakeLists.txt39
-rwxr-xr-xports_smp/cortex_a76ae_smp/gnu/example_build/build_threadx.sh87
-rwxr-xr-xports_smp/cortex_a76ae_smp/gnu/example_build/build_threadx_sample.sh109
-rw-r--r--ports_smp/cortex_a76ae_smp/gnu/example_build/readme.md39
-rw-r--r--ports_smp/cortex_a76ae_smp/gnu/example_build/sample_threadx/sample_threadx.launch23
-rw-r--r--ports_smp/cortex_a76ae_smp/gnu/example_build/sample_threadx/semihost_stub.S43
-rw-r--r--ports_smp/cortex_a76ae_smp/gnu/inc/tx_port.h2
-rw-r--r--ports_smp/cortex_a76ae_smp/gnu/src/tx_thread_smp_time_get.S3
-rw-r--r--ports_smp/cortex_a77_smp/ac6/example_build/sample_threadx/sample_threadx.launch22
-rw-r--r--ports_smp/cortex_a77_smp/ac6/inc/tx_port.h2
-rw-r--r--ports_smp/cortex_a77_smp/ac6/src/tx_thread_smp_time_get.S3
-rw-r--r--ports_smp/cortex_a77_smp/gnu/CMakeLists.txt39
-rwxr-xr-xports_smp/cortex_a77_smp/gnu/example_build/build_threadx.sh87
-rwxr-xr-xports_smp/cortex_a77_smp/gnu/example_build/build_threadx_sample.sh109
-rw-r--r--ports_smp/cortex_a77_smp/gnu/example_build/readme.md39
-rw-r--r--ports_smp/cortex_a77_smp/gnu/example_build/sample_threadx/sample_threadx.launch23
-rw-r--r--ports_smp/cortex_a77_smp/gnu/example_build/sample_threadx/semihost_stub.S43
-rw-r--r--ports_smp/cortex_a77_smp/gnu/inc/tx_port.h2
-rw-r--r--ports_smp/cortex_a77_smp/gnu/src/tx_thread_smp_time_get.S3
-rw-r--r--ports_smp/cortex_a78_smp/ac6/example_build/sample_threadx/.cproject2
-rw-r--r--ports_smp/cortex_a78_smp/ac6/example_build/sample_threadx/sample_threadx.launch100
-rw-r--r--ports_smp/cortex_a78_smp/ac6/example_build/tx/.cproject34
-rw-r--r--ports_smp/cortex_a78_smp/ac6/inc/tx_port.h2
-rw-r--r--ports_smp/cortex_a78_smp/ac6/src/tx_thread_context_restore.S78
-rw-r--r--ports_smp/cortex_a78_smp/ac6/src/tx_thread_context_save.S6
-rw-r--r--ports_smp/cortex_a78_smp/ac6/src/tx_thread_interrupt_control.S6
-rw-r--r--ports_smp/cortex_a78_smp/ac6/src/tx_thread_interrupt_disable.S6
-rw-r--r--ports_smp/cortex_a78_smp/ac6/src/tx_thread_interrupt_restore.S8
-rw-r--r--ports_smp/cortex_a78_smp/ac6/src/tx_thread_schedule.S8
-rw-r--r--ports_smp/cortex_a78_smp/ac6/src/tx_thread_smp_core_get.S8
-rw-r--r--ports_smp/cortex_a78_smp/ac6/src/tx_thread_smp_core_preempt.S9
-rw-r--r--ports_smp/cortex_a78_smp/ac6/src/tx_thread_smp_current_state_get.S8
-rw-r--r--ports_smp/cortex_a78_smp/ac6/src/tx_thread_smp_current_thread_get.S8
-rw-r--r--ports_smp/cortex_a78_smp/ac6/src/tx_thread_smp_initialize_wait.S8
-rw-r--r--ports_smp/cortex_a78_smp/ac6/src/tx_thread_smp_low_level_initialize.S8
-rw-r--r--ports_smp/cortex_a78_smp/ac6/src/tx_thread_smp_protect.S304
-rw-r--r--ports_smp/cortex_a78_smp/ac6/src/tx_thread_smp_time_get.S11
-rw-r--r--ports_smp/cortex_a78_smp/ac6/src/tx_thread_smp_unprotect.S13
-rw-r--r--ports_smp/cortex_a78_smp/ac6/src/tx_thread_stack_build.S6
-rw-r--r--ports_smp/cortex_a78_smp/ac6/src/tx_thread_system_return.S7
-rw-r--r--ports_smp/cortex_a78_smp/ac6/src/tx_timer_interrupt.S6
-rw-r--r--ports_smp/cortex_a78_smp/gnu/CMakeLists.txt39
-rwxr-xr-xports_smp/cortex_a78_smp/gnu/example_build/build_threadx.sh87
-rwxr-xr-xports_smp/cortex_a78_smp/gnu/example_build/build_threadx_sample.sh109
-rw-r--r--ports_smp/cortex_a78_smp/gnu/example_build/readme.md39
-rw-r--r--ports_smp/cortex_a78_smp/gnu/example_build/sample_threadx/sample_threadx.launch27
-rw-r--r--ports_smp/cortex_a78_smp/gnu/example_build/sample_threadx/semihost_stub.S43
-rw-r--r--ports_smp/cortex_a78_smp/gnu/example_build/tx/.cproject8
-rw-r--r--ports_smp/cortex_a78_smp/gnu/inc/tx_port.h2
-rw-r--r--ports_smp/cortex_a78_smp/gnu/src/tx_initialize_low_level.S6
-rw-r--r--ports_smp/cortex_a78_smp/gnu/src/tx_thread_context_restore.S78
-rw-r--r--ports_smp/cortex_a78_smp/gnu/src/tx_thread_context_save.S6
-rw-r--r--ports_smp/cortex_a78_smp/gnu/src/tx_thread_interrupt_control.S6
-rw-r--r--ports_smp/cortex_a78_smp/gnu/src/tx_thread_interrupt_disable.S6
-rw-r--r--ports_smp/cortex_a78_smp/gnu/src/tx_thread_interrupt_restore.S8
-rw-r--r--ports_smp/cortex_a78_smp/gnu/src/tx_thread_schedule.S8
-rw-r--r--ports_smp/cortex_a78_smp/gnu/src/tx_thread_smp_core_get.S8
-rw-r--r--ports_smp/cortex_a78_smp/gnu/src/tx_thread_smp_core_preempt.S9
-rw-r--r--ports_smp/cortex_a78_smp/gnu/src/tx_thread_smp_current_state_get.S8
-rw-r--r--ports_smp/cortex_a78_smp/gnu/src/tx_thread_smp_current_thread_get.S8
-rw-r--r--ports_smp/cortex_a78_smp/gnu/src/tx_thread_smp_initialize_wait.S8
-rw-r--r--ports_smp/cortex_a78_smp/gnu/src/tx_thread_smp_low_level_initialize.S8
-rw-r--r--ports_smp/cortex_a78_smp/gnu/src/tx_thread_smp_protect.S304
-rw-r--r--ports_smp/cortex_a78_smp/gnu/src/tx_thread_smp_time_get.S11
-rw-r--r--ports_smp/cortex_a78_smp/gnu/src/tx_thread_smp_unprotect.S13
-rw-r--r--ports_smp/cortex_a78_smp/gnu/src/tx_thread_stack_build.S6
-rw-r--r--ports_smp/cortex_a78_smp/gnu/src/tx_thread_system_return.S7
-rw-r--r--ports_smp/cortex_a78_smp/gnu/src/tx_timer_interrupt.S6
-rw-r--r--ports_smp/cortex_a7_smp/ac5/inc/tx_port.h2
-rw-r--r--ports_smp/cortex_a7_smp/ac5/src/tx_thread_context_restore.s79
-rw-r--r--ports_smp/cortex_a7_smp/ac5/src/tx_thread_context_save.s12
-rw-r--r--ports_smp/cortex_a7_smp/ac5/src/tx_thread_schedule.s4
-rw-r--r--ports_smp/cortex_a7_smp/ac5/src/tx_thread_smp_protect.s290
-rw-r--r--ports_smp/cortex_a7_smp/ac5/src/tx_thread_smp_protection_wait_list_macros.h312
-rw-r--r--ports_smp/cortex_a7_smp/ac5/src/tx_thread_smp_time_get.s6
-rw-r--r--ports_smp/cortex_a7_smp/ac5/src/tx_thread_smp_unprotect.s7
-rw-r--r--ports_smp/cortex_a7_smp/ac5/src/tx_thread_system_return.s7
-rw-r--r--ports_smp/cortex_a7_smp/ac5/src/tx_thread_vectored_context_save.s12
-rw-r--r--ports_smp/cortex_a7_smp/gnu/CMakeLists.txt37
-rwxr-xr-xports_smp/cortex_a7_smp/gnu/example_build/build_threadx.sh295
-rwxr-xr-xports_smp/cortex_a7_smp/gnu/example_build/build_threadx_sample.sh54
-rw-r--r--ports_smp/cortex_a7_smp/gnu/example_build/crt0.S101
-rw-r--r--ports_smp/cortex_a7_smp/gnu/inc/tx_port.h2
-rw-r--r--ports_smp/cortex_a7_smp/gnu/src/tx_thread_context_restore.S79
-rw-r--r--ports_smp/cortex_a7_smp/gnu/src/tx_thread_context_save.S12
-rw-r--r--ports_smp/cortex_a7_smp/gnu/src/tx_thread_schedule.S4
-rw-r--r--ports_smp/cortex_a7_smp/gnu/src/tx_thread_smp_protect.S289
-rw-r--r--ports_smp/cortex_a7_smp/gnu/src/tx_thread_smp_protection_wait_list_macros.h308
-rw-r--r--ports_smp/cortex_a7_smp/gnu/src/tx_thread_smp_time_get.S6
-rw-r--r--ports_smp/cortex_a7_smp/gnu/src/tx_thread_smp_unprotect.S (renamed from ports_smp/cortex_a7_smp/gnu/src/tx_thread_smp_unprotect.s)7
-rw-r--r--ports_smp/cortex_a7_smp/gnu/src/tx_thread_system_return.S7
-rw-r--r--ports_smp/cortex_a7_smp/gnu/src/tx_thread_vectored_context_save.S12
-rw-r--r--ports_smp/cortex_a9_smp/ac5/inc/tx_port.h2
-rw-r--r--ports_smp/cortex_a9_smp/ac5/src/tx_thread_context_restore.s80
-rw-r--r--ports_smp/cortex_a9_smp/ac5/src/tx_thread_context_save.s12
-rw-r--r--ports_smp/cortex_a9_smp/ac5/src/tx_thread_schedule.s4
-rw-r--r--ports_smp/cortex_a9_smp/ac5/src/tx_thread_smp_protect.s290
-rw-r--r--ports_smp/cortex_a9_smp/ac5/src/tx_thread_smp_protection_wait_list_macros.h314
-rw-r--r--ports_smp/cortex_a9_smp/ac5/src/tx_thread_smp_time_get.s5
-rw-r--r--ports_smp/cortex_a9_smp/ac5/src/tx_thread_smp_unprotect.s7
-rw-r--r--ports_smp/cortex_a9_smp/ac5/src/tx_thread_system_return.s7
-rw-r--r--ports_smp/cortex_a9_smp/ac5/src/tx_thread_vectored_context_save.s12
-rw-r--r--ports_smp/cortex_a9_smp/gnu/CMakeLists.txt1
-rwxr-xr-xports_smp/cortex_a9_smp/gnu/example_build/build_threadx.sh295
-rwxr-xr-xports_smp/cortex_a9_smp/gnu/example_build/build_threadx_sample.sh54
-rw-r--r--ports_smp/cortex_a9_smp/gnu/example_build/crt0.S101
-rw-r--r--ports_smp/cortex_a9_smp/gnu/inc/tx_port.h2
-rw-r--r--ports_smp/cortex_a9_smp/gnu/src/tx_thread_context_restore.S80
-rw-r--r--ports_smp/cortex_a9_smp/gnu/src/tx_thread_context_save.S12
-rw-r--r--ports_smp/cortex_a9_smp/gnu/src/tx_thread_schedule.S4
-rw-r--r--ports_smp/cortex_a9_smp/gnu/src/tx_thread_smp_protect.S290
-rw-r--r--ports_smp/cortex_a9_smp/gnu/src/tx_thread_smp_protection_wait_list_macros.h309
-rw-r--r--ports_smp/cortex_a9_smp/gnu/src/tx_thread_smp_time_get.S6
-rw-r--r--ports_smp/cortex_a9_smp/gnu/src/tx_thread_smp_unprotect.S7
-rw-r--r--ports_smp/cortex_a9_smp/gnu/src/tx_thread_system_return.S7
-rw-r--r--ports_smp/cortex_a9_smp/gnu/src/tx_thread_vectored_context_save.S12
-rw-r--r--ports_smp/cortex_r8_smp/ac5/inc/tx_port.h2
-rw-r--r--ports_smp/cortex_r8_smp/ac5/src/tx_thread_context_save.s11
-rw-r--r--ports_smp/cortex_r8_smp/ac5/src/tx_thread_smp_time_get.s3
-rw-r--r--ports_smp/cortex_r8_smp/ac5/src/tx_thread_system_return.s6
-rw-r--r--ports_smp/cortex_r8_smp/ac5/src/tx_thread_vectored_context_save.s11
-rw-r--r--ports_smp/linux/gnu/CMakeLists.txt41
-rw-r--r--ports_smp/linux/gnu/example_build/CMakeLists.txt17
-rw-r--r--ports_smp/linux/gnu/inc/tx_port.h28
-rw-r--r--ports_smp/linux/gnu/src/tx_thread_schedule.c41
-rw-r--r--ports_smp/linux/gnu/src/tx_thread_smp_unprotect.c15
-rw-r--r--ports_smp/linux/gnu/src/tx_thread_stack_build.c12
-rw-r--r--ports_smp/mips32_interaptiv_smp/gnu/CMakeLists.txt34
-rw-r--r--ports_smp/mips32_interaptiv_smp/gnu/inc/tx_port.h2
-rw-r--r--ports_smp/mips32_interaptiv_smp/green/inc/tx_port.h2
-rw-r--r--ports_smp/win64/vs_2022/CMakeLists.txt1
-rw-r--r--ports_smp/win64/vs_2022/inc/tx_port.h2
-rw-r--r--ports_smp/win64/vs_2022/src/tx_initialize_low_level.c3
-rw-r--r--ports_smp/win64/vs_2022/src/tx_thread_context_restore.c3
-rw-r--r--ports_smp/win64/vs_2022/src/tx_thread_context_save.c3
-rw-r--r--ports_smp/win64/vs_2022/src/tx_thread_schedule.c2
-rw-r--r--ports_smp/win64/vs_2022/src/tx_thread_smp_core_preempt.c2
-rw-r--r--ports_smp/win64/vs_2022/src/tx_thread_smp_current_state_get.c2
-rw-r--r--ports_smp/win64/vs_2022/src/tx_thread_smp_current_thread_get.c2
-rw-r--r--ports_smp/win64/vs_2022/src/tx_thread_smp_protect.c2
-rw-r--r--ports_smp/win64/vs_2022/src/tx_thread_smp_unprotect.c2
-rw-r--r--ports_smp/win64/vs_2022/src/tx_thread_stack_build.c2
-rw-r--r--ports_smp/win64/vs_2022/src/tx_thread_system_return.c2
344 files changed, 7381 insertions, 5555 deletions
diff --git a/ports_smp/arc_hs_smp/metaware/inc/tx_port.h b/ports_smp/arc_hs_smp/metaware/inc/tx_port.h
index 8b084160..335ec252 100644
--- a/ports_smp/arc_hs_smp/metaware/inc/tx_port.h
+++ b/ports_smp/arc_hs_smp/metaware/inc/tx_port.h
@@ -395,7 +395,7 @@ typedef struct TX_THREAD_SMP_PROTECT_STRUCT
#ifdef TX_THREAD_INIT
CHAR _tx_version_id[] =
- "(c) 2024 Microsoft Corp. (c) 2026-present Eclipse ThreadX contributors. * ThreadX SMP/ARC_HS/MetaWare Version 6.5.1.202602a *";
+ "(c) 2024 Microsoft Corp. (c) 2026-present Eclipse ThreadX contributors. * ThreadX SMP/ARC_HS/MetaWare Version 6.5.2.202603 *";
#else
extern CHAR _tx_version_id[];
#endif
diff --git a/ports_smp/arc_hs_smp/metaware/src/tx_thread_context_save.s b/ports_smp/arc_hs_smp/metaware/src/tx_thread_context_save.s
index 6014bdb2..13562cc8 100644
--- a/ports_smp/arc_hs_smp/metaware/src/tx_thread_context_save.s
+++ b/ports_smp/arc_hs_smp/metaware/src/tx_thread_context_save.s
@@ -1,5 +1,6 @@
;/***************************************************************************
; * Copyright (c) 2024 Microsoft Corporation
+; * 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
@@ -8,6 +9,7 @@
; * SPDX-License-Identifier: MIT
; **************************************************************************/
;
+; Portions of this file were generated with AI assistance.
;
;/**************************************************************************/
;/**************************************************************************/
@@ -187,10 +189,19 @@ __tx_thread_not_nested_save:
; _tx_thread_current_ptr[core] -> tx_thread_stack_ptr = sp;
;
st sp, [r1, 8] ; Save thread's stack pointer
+;
+; /* Switch to the system stack. */
+; sp = _tx_thread_system_stack_ptr[core];
+;
+ mov r1, _tx_thread_system_stack_ptr ; Build address of system stack pointer
+ add r1, r1, r3 ;
+ ld sp, [r1] ; Switch to system stack
.ifdef TX_ENABLE_EXECUTION_CHANGE_NOTIFY
;
-; /* Call the ISR enter function to indicate an ISR is executing. */
+; /* Call the ISR enter function to indicate an ISR is executing. The call is
+; made after the switch to the system stack so that it does not consume any
+; of the interrupted thread's stack. */
;
sub sp, sp, 32 ; Allocating some space on the stack
st blink, [sp, 16] ; Save blink
@@ -199,14 +210,8 @@ __tx_thread_not_nested_save:
ld blink, [sp, 16] ; Recover blink
add sp, sp, 32 ; Recover the stack space
.endif
-;
-; /* Switch to the system stack. */
-; sp = _tx_thread_system_stack_ptr[core];
-;
- mov r1, _tx_thread_system_stack_ptr ; Build address of system stack pointer
- add r1, r1, r3 ;
- j_s.d [blink] ; Return to calling ISR
- ld sp, [r1] ; Switch to system stack
+
+ j_s [blink] ; Return to calling ISR
;
; }
; else
diff --git a/ports_smp/cortex_a34_smp/ac6/example_build/sample_threadx/.cproject b/ports_smp/cortex_a34_smp/ac6/example_build/sample_threadx/.cproject
index dccae911..39ba5656 100644
--- a/ports_smp/cortex_a34_smp/ac6/example_build/sample_threadx/.cproject
+++ b/ports_smp/cortex_a34_smp/ac6/example_build/sample_threadx/.cproject
@@ -29,7 +29,7 @@
<toolChain id="com.arm.toolchain.v6.base.var.arm_compiler_6-6.1592753597" name="Arm Compiler 6" superClass="com.arm.toolchain.v6.base.var.arm_compiler_6-6">
- <option id="com.arm.toolchain.v6.base.options.target.cpu_fpu.1337922098" superClass="com.arm.toolchain.v6.base.options.target.cpu_fpu" useByScannerDiscovery="false" value="cortex-a34.AArch64.ARMv8.Neon.Crypto" valueType="string"/>
+ <option id="com.arm.toolchain.v6.base.options.target.cpu_fpu.1337922098" superClass="com.arm.toolchain.v6.base.options.target.cpu_fpu" useByScannerDiscovery="false" value="Cortex-A34.AArch64.ARMv8.Neon.Crypto" valueType="string"/>
<targetPlatform id="com.arm.toolchain.v6.base.var.arm_compiler_6-6.1592753597.2060144338" name=""/>
diff --git a/ports_smp/cortex_a34_smp/ac6/example_build/sample_threadx/sample_threadx.launch b/ports_smp/cortex_a34_smp/ac6/example_build/sample_threadx/sample_threadx.launch
index 9aefbdcd..3cbf2cc1 100644
--- a/ports_smp/cortex_a34_smp/ac6/example_build/sample_threadx/sample_threadx.launch
+++ b/ports_smp/cortex_a34_smp/ac6/example_build/sample_threadx/sample_threadx.launch
@@ -6,17 +6,17 @@
<stringAttribute key="ANDROID_PROCESS_NAME" value=""/>
<mapAttribute key="AverageDurationTracker">
<mapEntry key="*Fetching Data" value="34126331"/>
- <mapEntry key="*Fetching Data Model" value="1439173"/>
+ <mapEntry key="*Fetching Data Model" value="1887986"/>
<mapEntry key="*FunctionLoader" value="137168653"/>
- <mapEntry key="*list global low level symbols" value="2707112"/>
+ <mapEntry key="*list global low level symbols" value="3163826"/>
<mapEntry key="*loading memory from target" value="2367919"/>
- <mapEntry key="*loading values from target" value="8477514"/>
+ <mapEntry key="*loading values from target" value="8665557"/>
<mapEntry key="*trace" value="1527238"/>
- <mapEntry key="*updating expressions" value="101886453"/>
+ <mapEntry key="*updating expressions" value="25251903"/>
<mapEntry key="*updating local_variables" value="836905"/>
<mapEntry key="*updating registers" value="97090462"/>
<mapEntry key="*updating variables" value="877039"/>
- <mapEntry key="AddEventObserver" value="6587743"/>
+ <mapEntry key="AddEventObserver" value="5292071"/>
<mapEntry key="Evaluate" value="1689813"/>
<mapEntry key="ResumeToHere" value="20159012"/>
<mapEntry key="Retrieving globals list" value="21298708"/>
@@ -24,11 +24,11 @@
<mapEntry key="backtrace" value="21505977"/>
<mapEntry key="break" value="9764564"/>
<mapEntry key="checking tracepoints" value="372731"/>
- <mapEntry key="compute execution mode" value="557345"/>
+ <mapEntry key="compute execution mode" value="835755"/>
<mapEntry key="console" value="11946310"/>
- <mapEntry key="continue" value="12697403"/>
+ <mapEntry key="continue" value="21247618"/>
<mapEntry key="core" value="5451456"/>
- <mapEntry key="directory" value="4737162"/>
+ <mapEntry key="directory" value="4479981"/>
<mapEntry key="disable" value="2444670"/>
<mapEntry key="disassemble" value="64135505"/>
<mapEntry key="enable" value="5445745"/>
@@ -36,40 +36,41 @@
<mapEntry key="evaluate address" value="1056014"/>
<mapEntry key="finish" value="20115248"/>
<mapEntry key="get byte order" value="633302"/>
- <mapEntry key="get capabilities" value="548556"/>
- <mapEntry key="get execution addresss" value="438164"/>
- <mapEntry key="get source lines" value="3151194"/>
- <mapEntry key="get substitute paths" value="293110"/>
+ <mapEntry key="get capabilities" value="382078"/>
+ <mapEntry key="get execution addresss" value="403253"/>
+ <mapEntry key="get source lines" value="951928"/>
+ <mapEntry key="get substitute paths" value="523052"/>
<mapEntry key="getValidEncodings" value="1202320"/>
- <mapEntry key="initialize command help" value="68196070"/>
+ <mapEntry key="initialize command help" value="63855085"/>
<mapEntry key="interrupt" value="11210435"/>
- <mapEntry key="list breakpoint options" value="1264804"/>
- <mapEntry key="list breakpoints" value="1473749"/>
- <mapEntry key="list instruction sets" value="1512051"/>
- <mapEntry key="list signals" value="1314040"/>
+ <mapEntry key="list breakpoint options" value="2030851"/>
+ <mapEntry key="list breakpoints" value="1627224"/>
+ <mapEntry key="list instruction sets" value="1847125"/>
+ <mapEntry key="list signals" value="1953020"/>
<mapEntry key="list source files" value="573423"/>
- <mapEntry key="list watchpoint options" value="4130737"/>
- <mapEntry key="list watchpoints" value="739118"/>
- <mapEntry key="loadfile" value="308178719"/>
+ <mapEntry key="list watchpoint options" value="6057468"/>
+ <mapEntry key="list watchpoints" value="970059"/>
+ <mapEntry key="loadfile" value="386648009"/>
<mapEntry key="next" value="24266800"/>
<mapEntry key="query supports threads" value="215433"/>
- <mapEntry key="remove" value="3597385"/>
- <mapEntry key="run script" value="37326822"/>
- <mapEntry key="set CWD" value="4366642"/>
+ <mapEntry key="remove" value="7663692"/>
+ <mapEntry key="run script" value="44460661"/>
+ <mapEntry key="set CWD" value="5180571"/>
<mapEntry key="set breakpoint properties" value="10666013"/>
- <mapEntry key="set debug-from" value="1215725"/>
- <mapEntry key="set substitute-path" value="23083827"/>
- <mapEntry key="source use_model_semihosting.ds" value="7540462"/>
- <mapEntry key="start" value="36728254"/>
+ <mapEntry key="set debug-from" value="1157012"/>
+ <mapEntry key="set substitute-path" value="27245163"/>
+ <mapEntry key="source use_model_semihosting.ds" value="8849881"/>
+ <mapEntry key="start" value="50528177"/>
<mapEntry key="step" value="26461127"/>
<mapEntry key="stepi" value="29574773"/>
<mapEntry key="synchronizing trace ranges" value="21582"/>
<mapEntry key="target reset" value="32992642"/>
- <mapEntry key="toggleBreakpoint" value="7875634"/>
+ <mapEntry key="toggleBreakpoint" value="19462208"/>
<mapEntry key="updateBreakpointLocation" value="1868000"/>
- <mapEntry key="waitForTargetToStop" value="47515299"/>
+ <mapEntry key="waitForTargetToStop" value="52570549"/>
<mapEntry key="write expression" value="21220700"/>
</mapAttribute>
+ <stringAttribute key="CLOCK_SPEED" value="Auto"/>
<listAttribute key="DEBUG_TAB."/>
<stringAttribute key="DEBUG_TAB..RESOURCES.0.TYPE" value="SOURCE_DIR"/>
<stringAttribute key="DEBUG_TAB..RESOURCES.0.VALUE" value="${workspace_loc:/sample_threadx}"/>
@@ -89,15 +90,15 @@
<stringAttribute key="FILES.DEBUG_RESIDENT_ANDROID.RESOURCES.0.VALUE" value=""/>
<intAttribute key="FILES.DEBUG_RESIDENT_ANDROID.RESOURCES.COUNT" value="1"/>
<listAttribute key="FILES.DEBUG_RESIDENT_APP"/>
- <stringAttribute key="FILES.DEBUG_RESIDENT_APP.RESOURCES.0.TYPE" value="TARGET_WORKING_DIR"/>
+ <stringAttribute key="FILES.DEBUG_RESIDENT_APP.RESOURCES.0.TYPE" value="APPLICATION_ON_TARGET"/>
<stringAttribute key="FILES.DEBUG_RESIDENT_APP.RESOURCES.0.VALUE" value=""/>
- <stringAttribute key="FILES.DEBUG_RESIDENT_APP.RESOURCES.1.TYPE" value="APPLICATION_ON_TARGET"/>
+ <stringAttribute key="FILES.DEBUG_RESIDENT_APP.RESOURCES.1.TYPE" value="TARGET_WORKING_DIR"/>
<stringAttribute key="FILES.DEBUG_RESIDENT_APP.RESOURCES.1.VALUE" value=""/>
<intAttribute key="FILES.DEBUG_RESIDENT_APP.RESOURCES.COUNT" value="2"/>
<listAttribute key="FILES.DOWNLOAD_AND_DEBUG"/>
<stringAttribute key="FILES.DOWNLOAD_AND_DEBUG.RESOURCES.0.OPTION.ALSO_LOAD_SYMBOLS" value="false"/>
<stringAttribute key="FILES.DOWNLOAD_AND_DEBUG.RESOURCES.0.OPTION.ON_DEMAND_LOAD" value="true"/>
- <stringAttribute key="FILES.DOWNLOAD_AND_DEBUG.RESOURCES.0.TYPE" value="TARGET_WORKING_DIR"/>
+ <stringAttribute key="FILES.DOWNLOAD_AND_DEBUG.RESOURCES.0.TYPE" value="TARGET_DOWNLOAD_DIR"/>
<stringAttribute key="FILES.DOWNLOAD_AND_DEBUG.RESOURCES.0.VALUE" value=""/>
<stringAttribute key="FILES.DOWNLOAD_AND_DEBUG.RESOURCES.1.OPTION.ALSO_LOAD_SYMBOLS" value="false"/>
<stringAttribute key="FILES.DOWNLOAD_AND_DEBUG.RESOURCES.1.OPTION.ON_DEMAND_LOAD" value="true"/>
@@ -105,13 +106,13 @@
<stringAttribute key="FILES.DOWNLOAD_AND_DEBUG.RESOURCES.1.VALUE" value=""/>
<stringAttribute key="FILES.DOWNLOAD_AND_DEBUG.RESOURCES.2.OPTION.ALSO_LOAD_SYMBOLS" value="false"/>
<stringAttribute key="FILES.DOWNLOAD_AND_DEBUG.RESOURCES.2.OPTION.ON_DEMAND_LOAD" value="true"/>
- <stringAttribute key="FILES.DOWNLOAD_AND_DEBUG.RESOURCES.2.TYPE" value="TARGET_DOWNLOAD_DIR"/>
+ <stringAttribute key="FILES.DOWNLOAD_AND_DEBUG.RESOURCES.2.TYPE" value="TARGET_WORKING_DIR"/>
<stringAttribute key="FILES.DOWNLOAD_AND_DEBUG.RESOURCES.2.VALUE" value=""/>
<intAttribute key="FILES.DOWNLOAD_AND_DEBUG.RESOURCES.COUNT" value="3"/>
<listAttribute key="FILES.DOWNLOAD_DEBUG"/>
<stringAttribute key="FILES.DOWNLOAD_DEBUG.RESOURCES.0.OPTION.ALSO_LOAD_SYMBOLS" value="false"/>
<stringAttribute key="FILES.DOWNLOAD_DEBUG.RESOURCES.0.OPTION.ON_DEMAND_LOAD" value="true"/>
- <stringAttribute key="FILES.DOWNLOAD_DEBUG.RESOURCES.0.TYPE" value="TARGET_WORKING_DIR"/>
+ <stringAttribute key="FILES.DOWNLOAD_DEBUG.RESOURCES.0.TYPE" value="TARGET_DOWNLOAD_DIR"/>
<stringAttribute key="FILES.DOWNLOAD_DEBUG.RESOURCES.0.VALUE" value=""/>
<stringAttribute key="FILES.DOWNLOAD_DEBUG.RESOURCES.1.OPTION.ALSO_LOAD_SYMBOLS" value="false"/>
<stringAttribute key="FILES.DOWNLOAD_DEBUG.RESOURCES.1.OPTION.ON_DEMAND_LOAD" value="true"/>
@@ -119,7 +120,7 @@
<stringAttribute key="FILES.DOWNLOAD_DEBUG.RESOURCES.1.VALUE" value=""/>
<stringAttribute key="FILES.DOWNLOAD_DEBUG.RESOURCES.2.OPTION.ALSO_LOAD_SYMBOLS" value="false"/>
<stringAttribute key="FILES.DOWNLOAD_DEBUG.RESOURCES.2.OPTION.ON_DEMAND_LOAD" value="true"/>
- <stringAttribute key="FILES.DOWNLOAD_DEBUG.RESOURCES.2.TYPE" value="TARGET_DOWNLOAD_DIR"/>
+ <stringAttribute key="FILES.DOWNLOAD_DEBUG.RESOURCES.2.TYPE" value="TARGET_WORKING_DIR"/>
<stringAttribute key="FILES.DOWNLOAD_DEBUG.RESOURCES.2.VALUE" value=""/>
<intAttribute key="FILES.DOWNLOAD_DEBUG.RESOURCES.COUNT" value="3"/>
<intAttribute key="FILES.DOWNLOAD_DEBUG_ANDROID.RESOURCES.COUNT" value="0"/>
@@ -162,6 +163,8 @@
<intAttribute key="POST_TRIGGER_CAPTURE_SIZE" value="50"/>
<booleanAttribute key="RSE_USE_HOSTNAME" value="true"/>
<booleanAttribute key="STOP_ON_TRIGGER" value="false"/>
+ <booleanAttribute key="SWD" value="false"/>
+ <booleanAttribute key="SWJ" value="true"/>
<stringAttribute key="TCP_DISABLE_EXTENDED_MODE" value="true"/>
<booleanAttribute key="TCP_KILL_ON_EXIT" value="false"/>
<listAttribute key="TREE_NODE_PROPERTIES:debugger.view.ExpressionsView">
@@ -211,13 +214,6 @@
<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"/>
@@ -313,13 +309,13 @@
<listAttribute key="com.arm.debugger.views.common.AddressTracker.debugger.view.DisassemblyView.ranges">
<listEntry value="100"/>
</listAttribute>
- <stringAttribute key="config_db_activity_name" value="Cortex-A35x4 SMP"/>
+ <stringAttribute key="config_db_activity_name" value="Cortex-A34x4 SMP"/>
<stringAttribute key="config_db_connection_keys" value="dtsl_config dtsl_tracecapture_option connect_existing_model dtsl_config_script model_params model_iris config_file model_connection_address setup TCP_KILL_ON_EXIT TCP_DISABLE_EXTENDED_MODE"/>
<stringAttribute key="config_db_connection_type" value="Bare Metal Debug"/>
- <stringAttribute key="config_db_platform_name" value="Arm FVP - Base_A35x4"/>
+ <stringAttribute key="config_db_platform_name" value="Arm FVP - Base_A34x4"/>
<stringAttribute key="config_db_project_type" value="Bare Metal Debug"/>
<stringAttribute key="config_db_project_type_id" value="BARE_METAL"/>
- <stringAttribute key="config_db_taxonomy_id" value="/platform/armfvp/base_a35x4"/>
+ <stringAttribute key="config_db_taxonomy_id" value="/platform/armfvp/base_a34x4"/>
<stringAttribute key="config_file" value="CDB://iris_config.xml"/>
<booleanAttribute key="connectOnly" value="false"/>
<stringAttribute key="connect_existing_model" value="false"/>
@@ -363,7 +359,7 @@
<mapEntry key="6" value="NODE_TRANSFER_ELEMENT_COUNT,0;NODE_TRANSFER_ELEMENT_SIZE_IN_BYTES,4;NODE_TYPE,VALUE;FORMATTER,Unsigned Decimal"/>
<mapEntry key="7" value="NODE_TRANSFER_ELEMENT_COUNT,0;NODE_TRANSFER_ELEMENT_SIZE_IN_BYTES,4;NODE_TYPE,VALUE;FORMATTER,Unsigned Decimal"/>
</mapAttribute>
- <stringAttribute key="debugger.view.ExpressionsView:DebugOutlineColumnState" value="OutlineConfig1&#9;8&#9;0&#9;true&#9;true&#9;187&#9;-1&#9;true&#9;1&#9;false&#9;true&#9;90&#9;-1&#9;true&#9;2&#9;true&#9;true&#9;108&#9;-1&#9;true&#9;3&#9;true&#9;true&#9;57&#9;-1&#9;true&#9;4&#9;true&#9;true&#9;50&#9;-1&#9;true&#9;5&#9;true&#9;true&#9;37&#9;-1&#9;true&#9;6&#9;true&#9;true&#9;148&#9;-1&#9;true&#9;7&#9;true&#9;true&#9;53&#9;-1&#9;true"/>
+ <stringAttribute key="debugger.view.ExpressionsView:DebugOutlineColumnState" value="OutlineConfig1&#9;8&#9;0&#9;true&#9;true&#9;255&#9;-1&#9;true&#9;1&#9;false&#9;true&#9;127&#9;-1&#9;true&#9;2&#9;true&#9;true&#9;159&#9;-1&#9;true&#9;3&#9;true&#9;true&#9;75&#9;-1&#9;true&#9;4&#9;true&#9;true&#9;65&#9;-1&#9;true&#9;5&#9;true&#9;true&#9;48&#9;-1&#9;true&#9;6&#9;true&#9;true&#9;241&#9;-1&#9;true&#9;7&#9;true&#9;true&#9;69&#9;-1&#9;true"/>
<stringAttribute key="debugger.view.MemoryView" value="&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot;?&gt;&#10;&lt;page&gt;&#10;&#9;&lt;memoryView/&gt;&#10;&lt;/page&gt;&#10;"/>
<listAttribute key="debugger.view.MemoryView:current">
<listEntry value=""/>
@@ -386,24 +382,16 @@
<stringAttribute key="dtsl_options_file" value="default"/>
<stringAttribute key="dtsl_tracecapture_option" value="options.trace.traceCapture"/>
<booleanAttribute key="linuxOS" value="false"/>
- <stringAttribute key="model_connection_address" value=""/>
+ <stringAttribute key="model_connection_address" value="127.0.0.1:7100"/>
<stringAttribute key="model_iris" value="1"/>
<stringAttribute key="model_params" value="-C bp.secure_memory=false -C cache_state_modelled=0"/>
<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\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;"/>
+ <listEntry value="&quot;FVP_Base_Cortex-A34x4&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_smp/cortex_a34_smp/ac6/example_build/tx/.cproject b/ports_smp/cortex_a34_smp/ac6/example_build/tx/.cproject
index 742b0fa7..0b74b41a 100644
--- a/ports_smp/cortex_a34_smp/ac6/example_build/tx/.cproject
+++ b/ports_smp/cortex_a34_smp/ac6/example_build/tx/.cproject
@@ -7,7 +7,19 @@
<storageModule buildSystemId="org.eclipse.cdt.managedbuilder.core.configurationDataProvider" id="com.arm.eclipse.build.config.v6.lib.debug.base.1470528944" moduleId="org.eclipse.cdt.core.settings" name="Debug">
- <externalSettings/>
+ <externalSettings>
+
+ <externalSetting>
+
+ <entry flags="VALUE_WORKSPACE_PATH" kind="includePath" name="/tx"/>
+
+ <entry flags="VALUE_WORKSPACE_PATH" kind="libraryPath" name="/tx/Debug"/>
+
+ <entry flags="RESOLVED" kind="libraryFile" name="tx" srcPrefixMapping="" srcRootPath=""/>
+
+ </externalSetting>
+
+ </externalSettings>
<extensions>
@@ -29,7 +41,7 @@
<toolChain id="com.arm.toolchain.v6.lib.debug.base.var.arm_compiler_6-6.1684503312" name="Arm Compiler 6" superClass="com.arm.toolchain.v6.lib.debug.base.var.arm_compiler_6-6">
- <option id="com.arm.toolchain.v6.base.options.target.cpu_fpu.982423385" superClass="com.arm.toolchain.v6.base.options.target.cpu_fpu" useByScannerDiscovery="false" value="cortex-a34.AArch64.ARMv8.Neon.Crypto" valueType="string"/>
+ <option id="com.arm.toolchain.v6.base.options.target.cpu_fpu.982423385" superClass="com.arm.toolchain.v6.base.options.target.cpu_fpu" useByScannerDiscovery="false" value="Cortex-A34.AArch64.ARMv8.Neon.Crypto" valueType="string"/>
<targetPlatform id="com.arm.toolchain.v6.lib.debug.base.var.arm_compiler_6-6.1684503312.2127819066" name=""/>
@@ -105,9 +117,25 @@
</folderInfo>
+ <fileInfo id="com.arm.eclipse.build.config.v6.lib.debug.base.1470528944.214318543" name="tx_thread_timeout.c" rcbsApplicability="disable" resourcePath="src_generic/tx_thread_timeout.c" toolsToInvoke="com.arm.tool.c.compiler.v6.base.var.arm_compiler_6-6.2072709428.1899536638">
+
+ <tool id="com.arm.tool.c.compiler.v6.base.var.arm_compiler_6-6.2072709428.1899536638" name="Arm C Compiler 6" superClass="com.arm.tool.c.compiler.v6.base.var.arm_compiler_6-6.2072709428">
+
+ <inputType id="com.arm.tool.c.compiler.v6.base.input.1006773355" superClass="com.arm.tool.c.compiler.v6.base.input"/>
+
+ </tool>
+
+ </fileInfo>
+
+ <fileInfo id="com.arm.eclipse.build.config.v6.lib.debug.base.1470528944.1145515026" name="tx_misra.c" rcbsApplicability="disable" resourcePath="src_generic/tx_misra.c" toolsToInvoke="com.arm.tool.c.compiler.v6.base.var.arm_compiler_6-6.2072709428.1242981128">
+
+ <tool id="com.arm.tool.c.compiler.v6.base.var.arm_compiler_6-6.2072709428.1242981128" name="Arm C Compiler 6" superClass="com.arm.tool.c.compiler.v6.base.var.arm_compiler_6-6.2072709428"/>
+
+ </fileInfo>
+
<sourceEntries>
- <entry excluding="src_generic/tx_misra.c|src_generic/tx_thread_timeout.c" flags="VALUE_WORKSPACE_PATH|RESOLVED" kind="sourcePath" name=""/>
+ <entry flags="VALUE_WORKSPACE_PATH|RESOLVED" kind="sourcePath" name=""/>
</sourceEntries>
diff --git a/ports_smp/cortex_a34_smp/ac6/inc/tx_port.h b/ports_smp/cortex_a34_smp/ac6/inc/tx_port.h
index e97d78d5..38c86cb2 100644
--- a/ports_smp/cortex_a34_smp/ac6/inc/tx_port.h
+++ b/ports_smp/cortex_a34_smp/ac6/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_smp/cortex_a34_smp/ac6/src/tx_thread_context_restore.S b/ports_smp/cortex_a34_smp/ac6/src/tx_thread_context_restore.S
index 991248f5..5cd7a9df 100644
--- a/ports_smp/cortex_a34_smp/ac6/src/tx_thread_context_restore.S
+++ b/ports_smp/cortex_a34_smp/ac6/src/tx_thread_context_restore.S
@@ -19,7 +19,9 @@
/** */
/**************************************************************************/
/**************************************************************************/
-
+#ifdef TX_INCLUDE_USER_DEFINE_FILE
+#include "tx_user.h"
+#endif
.text
.align 3
@@ -28,7 +30,7 @@
/* FUNCTION RELEASE */
/* */
/* _tx_thread_context_restore ARMv8-A-SMP */
-/* 6.1.11 */
+/* 6.3.0 */
/* AUTHOR */
/* */
/* William E. Lamie, Microsoft Corporation */
@@ -277,6 +279,7 @@ __tx_thread_dont_save_ts:
/* Set bit indicating this thread is ready for execution. */
+ DMB ISH // Ensure that accesses to shared resource have completed
MOV x2, #1 // Build ready flag
STR w2, [x0, #260] // Set thread's ready flag
DMB ISH // Ensure that accesses to shared resource have completed
diff --git a/ports_smp/cortex_a34_smp/ac6/src/tx_thread_context_save.S b/ports_smp/cortex_a34_smp/ac6/src/tx_thread_context_save.S
index f43809f5..76641067 100644
--- a/ports_smp/cortex_a34_smp/ac6/src/tx_thread_context_save.S
+++ b/ports_smp/cortex_a34_smp/ac6/src/tx_thread_context_save.S
@@ -19,7 +19,9 @@
/** */
/**************************************************************************/
/**************************************************************************/
-
+#ifdef TX_INCLUDE_USER_DEFINE_FILE
+#include "tx_user.h"
+#endif
.text
.align 3
@@ -28,7 +30,7 @@
/* FUNCTION RELEASE */
/* */
/* _tx_thread_context_save ARMv8-A-SMP */
-/* 6.1.10 */
+/* 6.3.0 */
/* AUTHOR */
/* */
/* William E. Lamie, Microsoft Corporation */
diff --git a/ports_smp/cortex_a34_smp/ac6/src/tx_thread_interrupt_control.S b/ports_smp/cortex_a34_smp/ac6/src/tx_thread_interrupt_control.S
index d4235180..21ec2dd1 100644
--- a/ports_smp/cortex_a34_smp/ac6/src/tx_thread_interrupt_control.S
+++ b/ports_smp/cortex_a34_smp/ac6/src/tx_thread_interrupt_control.S
@@ -19,7 +19,9 @@
/** */
/**************************************************************************/
/**************************************************************************/
-
+#ifdef TX_INCLUDE_USER_DEFINE_FILE
+#include "tx_user.h"
+#endif
.text
.align 3
@@ -28,7 +30,7 @@
/* FUNCTION RELEASE */
/* */
/* _tx_thread_interrupt_control ARMv8-A */
-/* 6.1.10 */
+/* 6.3.0 */
/* AUTHOR */
/* */
/* William E. Lamie, Microsoft Corporation */
diff --git a/ports_smp/cortex_a34_smp/ac6/src/tx_thread_interrupt_disable.S b/ports_smp/cortex_a34_smp/ac6/src/tx_thread_interrupt_disable.S
index 08f0e7e1..af2ef874 100644
--- a/ports_smp/cortex_a34_smp/ac6/src/tx_thread_interrupt_disable.S
+++ b/ports_smp/cortex_a34_smp/ac6/src/tx_thread_interrupt_disable.S
@@ -19,7 +19,9 @@
/** */
/**************************************************************************/
/**************************************************************************/
-
+#ifdef TX_INCLUDE_USER_DEFINE_FILE
+#include "tx_user.h"
+#endif
.text
.align 3
@@ -28,7 +30,7 @@
/* FUNCTION RELEASE */
/* */
/* _tx_thread_interrupt_disable ARMv8-A */
-/* 6.1.10 */
+/* 6.3.0 */
/* AUTHOR */
/* */
/* William E. Lamie, Microsoft Corporation */
diff --git a/ports_smp/cortex_a34_smp/ac6/src/tx_thread_interrupt_restore.S b/ports_smp/cortex_a34_smp/ac6/src/tx_thread_interrupt_restore.S
index d0191c32..3e0780d0 100644
--- a/ports_smp/cortex_a34_smp/ac6/src/tx_thread_interrupt_restore.S
+++ b/ports_smp/cortex_a34_smp/ac6/src/tx_thread_interrupt_restore.S
@@ -19,7 +19,9 @@
/** */
/**************************************************************************/
/**************************************************************************/
-
+#ifdef TX_INCLUDE_USER_DEFINE_FILE
+#include "tx_user.h"
+#endif
.text
.align 3
@@ -27,8 +29,8 @@
/* */
/* FUNCTION RELEASE */
/* */
-/* _tx_thread_interrupt_restore ARMv8-A-SMP */
-/* 6.1.10 */
+/* _tx_thread_interrupt_restore ARMv8-A */
+/* 6.3.0 */
/* AUTHOR */
/* */
/* William E. Lamie, Microsoft Corporation */
diff --git a/ports_smp/cortex_a34_smp/ac6/src/tx_thread_schedule.S b/ports_smp/cortex_a34_smp/ac6/src/tx_thread_schedule.S
index 782491cc..de6b70dd 100644
--- a/ports_smp/cortex_a34_smp/ac6/src/tx_thread_schedule.S
+++ b/ports_smp/cortex_a34_smp/ac6/src/tx_thread_schedule.S
@@ -19,7 +19,9 @@
/** */
/**************************************************************************/
/**************************************************************************/
-
+#ifdef TX_INCLUDE_USER_DEFINE_FILE
+#include "tx_user.h"
+#endif
.text
.align 3
@@ -28,7 +30,7 @@
/* FUNCTION RELEASE */
/* */
/* _tx_thread_schedule ARMv8-A-SMP */
-/* 6.1.10 */
+/* 6.3.0 */
/* AUTHOR */
/* */
/* William E. Lamie, Microsoft Corporation */
@@ -156,7 +158,7 @@ _tx_thread_ready_for_execution:
LDR x2, =_tx_thread_current_ptr // Pickup address of current thread
STR x0, [x2, x20, LSL #3] // Setup current thread pointer
-
+ DMB ISH
LDR x1, [x1, x20, LSL #3] // Reload the execute pointer
CMP w0, w1 // Did it change?
BEQ _execute_pointer_did_not_change // If not, skip handling
diff --git a/ports_smp/cortex_a34_smp/ac6/src/tx_thread_smp_core_get.S b/ports_smp/cortex_a34_smp/ac6/src/tx_thread_smp_core_get.S
index 4ffb8cc6..ea14c901 100644
--- a/ports_smp/cortex_a34_smp/ac6/src/tx_thread_smp_core_get.S
+++ b/ports_smp/cortex_a34_smp/ac6/src/tx_thread_smp_core_get.S
@@ -19,7 +19,9 @@
/** */
/**************************************************************************/
/**************************************************************************/
-
+#ifdef TX_INCLUDE_USER_DEFINE_FILE
+#include "tx_user.h"
+#endif
.text
.align 3
@@ -27,8 +29,8 @@
/* */
/* FUNCTION RELEASE */
/* */
-/* _tx_thread_smp_core_get Cortex-A35-SMP/AC6 */
-/* 6.1.10 */
+/* _tx_thread_smp_core_get ARMv8-A-SMP */
+/* 6.3.0 */
/* AUTHOR */
/* */
/* William E. Lamie, Microsoft Corporation */
diff --git a/ports_smp/cortex_a34_smp/ac6/src/tx_thread_smp_core_preempt.S b/ports_smp/cortex_a34_smp/ac6/src/tx_thread_smp_core_preempt.S
index 8dc6933c..1d28907f 100644
--- a/ports_smp/cortex_a34_smp/ac6/src/tx_thread_smp_core_preempt.S
+++ b/ports_smp/cortex_a34_smp/ac6/src/tx_thread_smp_core_preempt.S
@@ -19,6 +19,11 @@
/** */
/**************************************************************************/
/**************************************************************************/
+#ifdef TX_INCLUDE_USER_DEFINE_FILE
+#include "tx_user.h"
+#endif
+
+#define ICC_SGI1R_EL1 S3_0_C12_C11_5
.text
@@ -27,8 +32,8 @@
/* */
/* FUNCTION RELEASE */
/* */
-/* _tx_thread_smp_core_preempt Cortex-A35-SMP/AC6 */
-/* 6.1.10 */
+/* _tx_thread_smp_core_preempt ARMv8-A-SMP */
+/* 6.3.0 */
/* AUTHOR */
/* */
/* William E. Lamie, Microsoft Corporation */
diff --git a/ports_smp/cortex_a34_smp/ac6/src/tx_thread_smp_current_state_get.S b/ports_smp/cortex_a34_smp/ac6/src/tx_thread_smp_current_state_get.S
index edae94d5..707b41d2 100644
--- a/ports_smp/cortex_a34_smp/ac6/src/tx_thread_smp_current_state_get.S
+++ b/ports_smp/cortex_a34_smp/ac6/src/tx_thread_smp_current_state_get.S
@@ -19,7 +19,9 @@
/** */
/**************************************************************************/
/**************************************************************************/
-
+#ifdef TX_INCLUDE_USER_DEFINE_FILE
+#include "tx_user.h"
+#endif
.text
.align 3
@@ -27,8 +29,8 @@
/* */
/* FUNCTION RELEASE */
/* */
-/* _tx_thread_smp_current_state_get Cortex-A35-SMP/AC6 */
-/* 6.1.10 */
+/* _tx_thread_smp_current_state_get ARMv8-A-SMP */
+/* 6.3.0 */
/* AUTHOR */
/* */
/* William E. Lamie, Microsoft Corporation */
diff --git a/ports_smp/cortex_a34_smp/ac6/src/tx_thread_smp_current_thread_get.S b/ports_smp/cortex_a34_smp/ac6/src/tx_thread_smp_current_thread_get.S
index dd740e05..6c4bc9af 100644
--- a/ports_smp/cortex_a34_smp/ac6/src/tx_thread_smp_current_thread_get.S
+++ b/ports_smp/cortex_a34_smp/ac6/src/tx_thread_smp_current_thread_get.S
@@ -19,7 +19,9 @@
/** */
/**************************************************************************/
/**************************************************************************/
-
+#ifdef TX_INCLUDE_USER_DEFINE_FILE
+#include "tx_user.h"
+#endif
.text
.align 3
@@ -27,8 +29,8 @@
/* */
/* FUNCTION RELEASE */
/* */
-/* _tx_thread_smp_current_thread_get Cortex-A35-SMP/AC6 */
-/* 6.1.10 */
+/* _tx_thread_smp_current_thread_get ARMv8-A-SMP */
+/* 6.3.0 */
/* AUTHOR */
/* */
/* William E. Lamie, Microsoft Corporation */
diff --git a/ports_smp/cortex_a34_smp/ac6/src/tx_thread_smp_initialize_wait.S b/ports_smp/cortex_a34_smp/ac6/src/tx_thread_smp_initialize_wait.S
index 985136b5..defd791c 100644
--- a/ports_smp/cortex_a34_smp/ac6/src/tx_thread_smp_initialize_wait.S
+++ b/ports_smp/cortex_a34_smp/ac6/src/tx_thread_smp_initialize_wait.S
@@ -19,7 +19,9 @@
/** */
/**************************************************************************/
/**************************************************************************/
-
+#ifdef TX_INCLUDE_USER_DEFINE_FILE
+#include "tx_user.h"
+#endif
.text
.align 3
@@ -27,8 +29,8 @@
/* */
/* FUNCTION RELEASE */
/* */
-/* _tx_thread_smp_initialize_wait Cortex-A35-SMP/AC6 */
-/* 6.1.10 */
+/* _tx_thread_smp_initialize_wait ARMv8-A-SMP */
+/* 6.3.0 */
/* AUTHOR */
/* */
/* William E. Lamie, Microsoft Corporation */
diff --git a/ports_smp/cortex_a34_smp/ac6/src/tx_thread_smp_low_level_initialize.S b/ports_smp/cortex_a34_smp/ac6/src/tx_thread_smp_low_level_initialize.S
index 64b854d0..99b20d24 100644
--- a/ports_smp/cortex_a34_smp/ac6/src/tx_thread_smp_low_level_initialize.S
+++ b/ports_smp/cortex_a34_smp/ac6/src/tx_thread_smp_low_level_initialize.S
@@ -19,7 +19,9 @@
/** */
/**************************************************************************/
/**************************************************************************/
-
+#ifdef TX_INCLUDE_USER_DEFINE_FILE
+#include "tx_user.h"
+#endif
.text
.align 3
@@ -27,8 +29,8 @@
/* */
/* FUNCTION RELEASE */
/* */
-/* _tx_thread_smp_low_level_initialize Cortex-A35-SMP/AC6 */
-/* 6.1.10 */
+/* _tx_thread_smp_low_level_initialize ARMv8-A-SMP */
+/* 6.3.0 */
/* AUTHOR */
/* */
/* William E. Lamie, Microsoft Corporation */
diff --git a/ports_smp/cortex_a34_smp/ac6/src/tx_thread_smp_protect.S b/ports_smp/cortex_a34_smp/ac6/src/tx_thread_smp_protect.S
index 4a48c56c..1155a3fa 100644
--- a/ports_smp/cortex_a34_smp/ac6/src/tx_thread_smp_protect.S
+++ b/ports_smp/cortex_a34_smp/ac6/src/tx_thread_smp_protect.S
@@ -19,7 +19,9 @@
/** */
/**************************************************************************/
/**************************************************************************/
-
+#ifdef TX_INCLUDE_USER_DEFINE_FILE
+#include "tx_user.h"
+#endif
/* Include macros for modifying the wait list. */
#include "tx_thread_smp_protection_wait_list_macros.h"
@@ -31,8 +33,8 @@
/* */
/* FUNCTION RELEASE */
/* */
-/* _tx_thread_smp_protect Cortex-A35-SMP/AC6 */
-/* 6.1.11 */
+/* _tx_thread_smp_protect ARMv8-A-SMP */
+/* 6.3.0 */
/* AUTHOR */
/* */
/* William E. Lamie, Microsoft Corporation */
diff --git a/ports_smp/cortex_a34_smp/ac6/src/tx_thread_smp_time_get.S b/ports_smp/cortex_a34_smp/ac6/src/tx_thread_smp_time_get.S
index f3045738..4bb9f1cb 100644
--- a/ports_smp/cortex_a34_smp/ac6/src/tx_thread_smp_time_get.S
+++ b/ports_smp/cortex_a34_smp/ac6/src/tx_thread_smp_time_get.S
@@ -9,6 +9,7 @@
* SPDX-License-Identifier: MIT
**************************************************************************/
+// Portions of this file were generated with AI assistance.
/**************************************************************************/
/**************************************************************************/
@@ -19,7 +20,9 @@
/** */
/**************************************************************************/
/**************************************************************************/
-
+#ifdef TX_INCLUDE_USER_DEFINE_FILE
+#include "tx_user.h"
+#endif
.text
.align 3
@@ -27,8 +30,8 @@
/* */
/* FUNCTION RELEASE */
/* */
-/* _tx_thread_smp_time_get Cortex-A35-SMP/AC6 */
-/* 6.1.10 */
+/* _tx_thread_smp_time_get ARMv8-A-SMP */
+/* 6.3.0 */
/* AUTHOR */
/* */
/* William E. Lamie, Microsoft Corporation */
@@ -58,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_smp/cortex_a34_smp/ac6/src/tx_thread_smp_unprotect.S b/ports_smp/cortex_a34_smp/ac6/src/tx_thread_smp_unprotect.S
index 4b5bd9a2..680e8bc8 100644
--- a/ports_smp/cortex_a34_smp/ac6/src/tx_thread_smp_unprotect.S
+++ b/ports_smp/cortex_a34_smp/ac6/src/tx_thread_smp_unprotect.S
@@ -19,7 +19,9 @@
/** */
/**************************************************************************/
/**************************************************************************/
-
+#ifdef TX_INCLUDE_USER_DEFINE_FILE
+#include "tx_user.h"
+#endif
.text
.align 3
@@ -27,8 +29,8 @@
/* */
/* FUNCTION RELEASE */
/* */
-/* _tx_thread_smp_unprotect Cortex-A35-SMP/AC6 */
-/* 6.1.11 */
+/* _tx_thread_smp_unprotect ARMv8-A-SMP */
+/* 6.3.0 */
/* AUTHOR */
/* */
/* William E. Lamie, Microsoft Corporation */
diff --git a/ports_smp/cortex_a34_smp/ac6/src/tx_thread_stack_build.S b/ports_smp/cortex_a34_smp/ac6/src/tx_thread_stack_build.S
index fa11a65c..581e259e 100644
--- a/ports_smp/cortex_a34_smp/ac6/src/tx_thread_stack_build.S
+++ b/ports_smp/cortex_a34_smp/ac6/src/tx_thread_stack_build.S
@@ -19,7 +19,9 @@
/** */
/**************************************************************************/
/**************************************************************************/
-
+#ifdef TX_INCLUDE_USER_DEFINE_FILE
+#include "tx_user.h"
+#endif
.text
.align 3
@@ -28,7 +30,7 @@
/* FUNCTION RELEASE */
/* */
/* _tx_thread_stack_build ARMv8-A-SMP */
-/* 6.1.10 */
+/* 6.3.0 */
/* AUTHOR */
/* */
/* William E. Lamie, Microsoft Corporation */
diff --git a/ports_smp/cortex_a34_smp/ac6/src/tx_thread_system_return.S b/ports_smp/cortex_a34_smp/ac6/src/tx_thread_system_return.S
index 4eebb9aa..23c75241 100644
--- a/ports_smp/cortex_a34_smp/ac6/src/tx_thread_system_return.S
+++ b/ports_smp/cortex_a34_smp/ac6/src/tx_thread_system_return.S
@@ -19,7 +19,9 @@
/** */
/**************************************************************************/
/**************************************************************************/
-
+#ifdef TX_INCLUDE_USER_DEFINE_FILE
+#include "tx_user.h"
+#endif
.text
.align 3
@@ -28,7 +30,7 @@
/* FUNCTION RELEASE */
/* */
/* _tx_thread_system_return ARMv8-A-SMP */
-/* 6.1.10 */
+/* 6.3.0 */
/* AUTHOR */
/* */
/* William E. Lamie, Microsoft Corporation */
@@ -159,6 +161,7 @@ __tx_thread_dont_save_ts:
/* Set ready bit in thread control block. */
+ DMB ISH // Ensure that accesses to shared resource have completed
MOV x3, #1 // Build ready value
STR w3, [x6, #260] // Make the thread ready
DMB ISH //
diff --git a/ports_smp/cortex_a34_smp/ac6/src/tx_timer_interrupt.S b/ports_smp/cortex_a34_smp/ac6/src/tx_timer_interrupt.S
index 6f90e5d1..5c6a6bc2 100644
--- a/ports_smp/cortex_a34_smp/ac6/src/tx_timer_interrupt.S
+++ b/ports_smp/cortex_a34_smp/ac6/src/tx_timer_interrupt.S
@@ -19,7 +19,9 @@
/** */
/**************************************************************************/
/**************************************************************************/
-
+#ifdef TX_INCLUDE_USER_DEFINE_FILE
+#include "tx_user.h"
+#endif
.text
.align 3
@@ -28,7 +30,7 @@
/* FUNCTION RELEASE */
/* */
/* _tx_timer_interrupt ARMv8-A-SMP */
-/* 6.1.10 */
+/* 6.3.0 */
/* AUTHOR */
/* */
/* William E. Lamie, Microsoft Corporation */
diff --git a/ports_smp/cortex_a34_smp/gnu/CMakeLists.txt b/ports_smp/cortex_a34_smp/gnu/CMakeLists.txt
new file mode 100644
index 00000000..36f7492b
--- /dev/null
+++ b/ports_smp/cortex_a34_smp/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_smp/cortex_a34_smp/gnu/example_build/build_threadx.sh b/ports_smp/cortex_a34_smp/gnu/example_build/build_threadx.sh
new file mode 100755
index 00000000..b3b2cd36
--- /dev/null
+++ b/ports_smp/cortex_a34_smp/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_smp/cortex_a34_smp/gnu/example_build/build_threadx_sample.sh b/ports_smp/cortex_a34_smp/gnu/example_build/build_threadx_sample.sh
new file mode 100755
index 00000000..94248a88
--- /dev/null
+++ b/ports_smp/cortex_a34_smp/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_smp/cortex_a34_smp/gnu/example_build/readme.md b/ports_smp/cortex_a34_smp/gnu/example_build/readme.md
new file mode 100644
index 00000000..3c52a7da
--- /dev/null
+++ b/ports_smp/cortex_a34_smp/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_smp/cortex_a34_smp/gnu/example_build/sample_threadx/sample_threadx.launch b/ports_smp/cortex_a34_smp/gnu/example_build/sample_threadx/sample_threadx.launch
index d583631e..385b43c3 100644
--- a/ports_smp/cortex_a34_smp/gnu/example_build/sample_threadx/sample_threadx.launch
+++ b/ports_smp/cortex_a34_smp/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"/>
@@ -345,13 +338,13 @@
<listAttribute key="com.arm.debugger.views.common.AddressTracker.debugger.view.DisassemblyView.ranges">
<listEntry value="100"/>
</listAttribute>
- <stringAttribute key="config_db_activity_name" value="Cortex-A35x4 SMP"/>
+ <stringAttribute key="config_db_activity_name" value="Cortex-A34x4 SMP"/>
<stringAttribute key="config_db_connection_keys" value="dtsl_config dtsl_tracecapture_option connect_existing_model dtsl_config_script model_params model_iris config_file model_connection_address setup TCP_KILL_ON_EXIT TCP_DISABLE_EXTENDED_MODE"/>
<stringAttribute key="config_db_connection_type" value="Bare Metal Debug"/>
- <stringAttribute key="config_db_platform_name" value="Arm FVP - Base_A35x4"/>
+ <stringAttribute key="config_db_platform_name" value="Arm FVP - Base_A34x4"/>
<stringAttribute key="config_db_project_type" value="Bare Metal Debug"/>
<stringAttribute key="config_db_project_type_id" value="BARE_METAL"/>
- <stringAttribute key="config_db_taxonomy_id" value="/platform/armfvp/base_a35x4"/>
+ <stringAttribute key="config_db_taxonomy_id" value="/platform/armfvp/base_a34x4"/>
<stringAttribute key="config_file" value="CDB://iris_config.xml"/>
<booleanAttribute key="connectOnly" value="false"/>
<stringAttribute key="connect_existing_model" value="false"/>
@@ -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;"/>
+ <listEntry value="&quot;FVP_Base_Cortex-A34x4&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_smp/cortex_a34_smp/gnu/example_build/sample_threadx/semihost_stub.S b/ports_smp/cortex_a34_smp/gnu/example_build/sample_threadx/semihost_stub.S
new file mode 100644
index 00000000..c456875d
--- /dev/null
+++ b/ports_smp/cortex_a34_smp/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_smp/cortex_a34_smp/gnu/example_build/tx/.cproject b/ports_smp/cortex_a34_smp/gnu/example_build/tx/.cproject
index 11d7c2fe..e3f31405 100644
--- a/ports_smp/cortex_a34_smp/gnu/example_build/tx/.cproject
+++ b/ports_smp/cortex_a34_smp/gnu/example_build/tx/.cproject
@@ -129,9 +129,15 @@
</folderInfo>
+ <fileInfo id="com.arm.eclipse.cdt.managedbuild.ds5.gcc.baremetal.config.exe.debug.var.gcc-8.3.0-aarch64-elf.794347674.1482422597" name="tx_misra.c" rcbsApplicability="disable" resourcePath="src_generic/tx_misra.c" toolsToInvoke="com.arm.eclipse.cdt.managedbuild.ds5.gcc.baremetal.tool.c.compiler.var.gcc-8.3.0-aarch64-elf.1247168701.1451532610">
+
+ <tool id="com.arm.eclipse.cdt.managedbuild.ds5.gcc.baremetal.tool.c.compiler.var.gcc-8.3.0-aarch64-elf.1247168701.1451532610" name="GCC C Compiler 8.3.0 [aarch64-elf]" superClass="com.arm.eclipse.cdt.managedbuild.ds5.gcc.baremetal.tool.c.compiler.var.gcc-8.3.0-aarch64-elf.1247168701"/>
+
+ </fileInfo>
+
<sourceEntries>
- <entry excluding="src_generic/tx_misra.c|src_generic/tx_thread_timeout.c" flags="VALUE_WORKSPACE_PATH|RESOLVED" kind="sourcePath" name=""/>
+ <entry flags="VALUE_WORKSPACE_PATH|RESOLVED" kind="sourcePath" name=""/>
</sourceEntries>
diff --git a/ports_smp/cortex_a34_smp/gnu/inc/tx_port.h b/ports_smp/cortex_a34_smp/gnu/inc/tx_port.h
index e97d78d5..38c86cb2 100644
--- a/ports_smp/cortex_a34_smp/gnu/inc/tx_port.h
+++ b/ports_smp/cortex_a34_smp/gnu/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_smp/cortex_a34_smp/gnu/src/tx_initialize_low_level.S b/ports_smp/cortex_a34_smp/gnu/src/tx_initialize_low_level.S
index 43d87225..efb08b80 100644
--- a/ports_smp/cortex_a34_smp/gnu/src/tx_initialize_low_level.S
+++ b/ports_smp/cortex_a34_smp/gnu/src/tx_initialize_low_level.S
@@ -19,7 +19,9 @@
/** */
/**************************************************************************/
/**************************************************************************/
-
+#ifdef TX_INCLUDE_USER_DEFINE_FILE
+#include "tx_user.h"
+#endif
.text
.align 3
@@ -28,7 +30,7 @@
/* FUNCTION RELEASE */
/* */
/* _tx_initialize_low_level ARMv8-A-SMP */
-/* 6.1.10 */
+/* 6.3.0 */
/* AUTHOR */
/* */
/* William E. Lamie, Microsoft Corporation */
diff --git a/ports_smp/cortex_a34_smp/gnu/src/tx_thread_context_restore.S b/ports_smp/cortex_a34_smp/gnu/src/tx_thread_context_restore.S
index 991248f5..5cd7a9df 100644
--- a/ports_smp/cortex_a34_smp/gnu/src/tx_thread_context_restore.S
+++ b/ports_smp/cortex_a34_smp/gnu/src/tx_thread_context_restore.S
@@ -19,7 +19,9 @@
/** */
/**************************************************************************/
/**************************************************************************/
-
+#ifdef TX_INCLUDE_USER_DEFINE_FILE
+#include "tx_user.h"
+#endif
.text
.align 3
@@ -28,7 +30,7 @@
/* FUNCTION RELEASE */
/* */
/* _tx_thread_context_restore ARMv8-A-SMP */
-/* 6.1.11 */
+/* 6.3.0 */
/* AUTHOR */
/* */
/* William E. Lamie, Microsoft Corporation */
@@ -277,6 +279,7 @@ __tx_thread_dont_save_ts:
/* Set bit indicating this thread is ready for execution. */
+ DMB ISH // Ensure that accesses to shared resource have completed
MOV x2, #1 // Build ready flag
STR w2, [x0, #260] // Set thread's ready flag
DMB ISH // Ensure that accesses to shared resource have completed
diff --git a/ports_smp/cortex_a34_smp/gnu/src/tx_thread_context_save.S b/ports_smp/cortex_a34_smp/gnu/src/tx_thread_context_save.S
index f43809f5..76641067 100644
--- a/ports_smp/cortex_a34_smp/gnu/src/tx_thread_context_save.S
+++ b/ports_smp/cortex_a34_smp/gnu/src/tx_thread_context_save.S
@@ -19,7 +19,9 @@
/** */
/**************************************************************************/
/**************************************************************************/
-
+#ifdef TX_INCLUDE_USER_DEFINE_FILE
+#include "tx_user.h"
+#endif
.text
.align 3
@@ -28,7 +30,7 @@
/* FUNCTION RELEASE */
/* */
/* _tx_thread_context_save ARMv8-A-SMP */
-/* 6.1.10 */
+/* 6.3.0 */
/* AUTHOR */
/* */
/* William E. Lamie, Microsoft Corporation */
diff --git a/ports_smp/cortex_a34_smp/gnu/src/tx_thread_interrupt_control.S b/ports_smp/cortex_a34_smp/gnu/src/tx_thread_interrupt_control.S
index d4235180..21ec2dd1 100644
--- a/ports_smp/cortex_a34_smp/gnu/src/tx_thread_interrupt_control.S
+++ b/ports_smp/cortex_a34_smp/gnu/src/tx_thread_interrupt_control.S
@@ -19,7 +19,9 @@
/** */
/**************************************************************************/
/**************************************************************************/
-
+#ifdef TX_INCLUDE_USER_DEFINE_FILE
+#include "tx_user.h"
+#endif
.text
.align 3
@@ -28,7 +30,7 @@
/* FUNCTION RELEASE */
/* */
/* _tx_thread_interrupt_control ARMv8-A */
-/* 6.1.10 */
+/* 6.3.0 */
/* AUTHOR */
/* */
/* William E. Lamie, Microsoft Corporation */
diff --git a/ports_smp/cortex_a34_smp/gnu/src/tx_thread_interrupt_disable.S b/ports_smp/cortex_a34_smp/gnu/src/tx_thread_interrupt_disable.S
index 08f0e7e1..af2ef874 100644
--- a/ports_smp/cortex_a34_smp/gnu/src/tx_thread_interrupt_disable.S
+++ b/ports_smp/cortex_a34_smp/gnu/src/tx_thread_interrupt_disable.S
@@ -19,7 +19,9 @@
/** */
/**************************************************************************/
/**************************************************************************/
-
+#ifdef TX_INCLUDE_USER_DEFINE_FILE
+#include "tx_user.h"
+#endif
.text
.align 3
@@ -28,7 +30,7 @@
/* FUNCTION RELEASE */
/* */
/* _tx_thread_interrupt_disable ARMv8-A */
-/* 6.1.10 */
+/* 6.3.0 */
/* AUTHOR */
/* */
/* William E. Lamie, Microsoft Corporation */
diff --git a/ports_smp/cortex_a34_smp/gnu/src/tx_thread_interrupt_restore.S b/ports_smp/cortex_a34_smp/gnu/src/tx_thread_interrupt_restore.S
index d0191c32..3e0780d0 100644
--- a/ports_smp/cortex_a34_smp/gnu/src/tx_thread_interrupt_restore.S
+++ b/ports_smp/cortex_a34_smp/gnu/src/tx_thread_interrupt_restore.S
@@ -19,7 +19,9 @@
/** */
/**************************************************************************/
/**************************************************************************/
-
+#ifdef TX_INCLUDE_USER_DEFINE_FILE
+#include "tx_user.h"
+#endif
.text
.align 3
@@ -27,8 +29,8 @@
/* */
/* FUNCTION RELEASE */
/* */
-/* _tx_thread_interrupt_restore ARMv8-A-SMP */
-/* 6.1.10 */
+/* _tx_thread_interrupt_restore ARMv8-A */
+/* 6.3.0 */
/* AUTHOR */
/* */
/* William E. Lamie, Microsoft Corporation */
diff --git a/ports_smp/cortex_a34_smp/gnu/src/tx_thread_schedule.S b/ports_smp/cortex_a34_smp/gnu/src/tx_thread_schedule.S
index 782491cc..de6b70dd 100644
--- a/ports_smp/cortex_a34_smp/gnu/src/tx_thread_schedule.S
+++ b/ports_smp/cortex_a34_smp/gnu/src/tx_thread_schedule.S
@@ -19,7 +19,9 @@
/** */
/**************************************************************************/
/**************************************************************************/
-
+#ifdef TX_INCLUDE_USER_DEFINE_FILE
+#include "tx_user.h"
+#endif
.text
.align 3
@@ -28,7 +30,7 @@
/* FUNCTION RELEASE */
/* */
/* _tx_thread_schedule ARMv8-A-SMP */
-/* 6.1.10 */
+/* 6.3.0 */
/* AUTHOR */
/* */
/* William E. Lamie, Microsoft Corporation */
@@ -156,7 +158,7 @@ _tx_thread_ready_for_execution:
LDR x2, =_tx_thread_current_ptr // Pickup address of current thread
STR x0, [x2, x20, LSL #3] // Setup current thread pointer
-
+ DMB ISH
LDR x1, [x1, x20, LSL #3] // Reload the execute pointer
CMP w0, w1 // Did it change?
BEQ _execute_pointer_did_not_change // If not, skip handling
diff --git a/ports_smp/cortex_a34_smp/gnu/src/tx_thread_smp_core_get.S b/ports_smp/cortex_a34_smp/gnu/src/tx_thread_smp_core_get.S
index 4ffb8cc6..ea14c901 100644
--- a/ports_smp/cortex_a34_smp/gnu/src/tx_thread_smp_core_get.S
+++ b/ports_smp/cortex_a34_smp/gnu/src/tx_thread_smp_core_get.S
@@ -19,7 +19,9 @@
/** */
/**************************************************************************/
/**************************************************************************/
-
+#ifdef TX_INCLUDE_USER_DEFINE_FILE
+#include "tx_user.h"
+#endif
.text
.align 3
@@ -27,8 +29,8 @@
/* */
/* FUNCTION RELEASE */
/* */
-/* _tx_thread_smp_core_get Cortex-A35-SMP/AC6 */
-/* 6.1.10 */
+/* _tx_thread_smp_core_get ARMv8-A-SMP */
+/* 6.3.0 */
/* AUTHOR */
/* */
/* William E. Lamie, Microsoft Corporation */
diff --git a/ports_smp/cortex_a34_smp/gnu/src/tx_thread_smp_core_preempt.S b/ports_smp/cortex_a34_smp/gnu/src/tx_thread_smp_core_preempt.S
index 8dc6933c..1d28907f 100644
--- a/ports_smp/cortex_a34_smp/gnu/src/tx_thread_smp_core_preempt.S
+++ b/ports_smp/cortex_a34_smp/gnu/src/tx_thread_smp_core_preempt.S
@@ -19,6 +19,11 @@
/** */
/**************************************************************************/
/**************************************************************************/
+#ifdef TX_INCLUDE_USER_DEFINE_FILE
+#include "tx_user.h"
+#endif
+
+#define ICC_SGI1R_EL1 S3_0_C12_C11_5
.text
@@ -27,8 +32,8 @@
/* */
/* FUNCTION RELEASE */
/* */
-/* _tx_thread_smp_core_preempt Cortex-A35-SMP/AC6 */
-/* 6.1.10 */
+/* _tx_thread_smp_core_preempt ARMv8-A-SMP */
+/* 6.3.0 */
/* AUTHOR */
/* */
/* William E. Lamie, Microsoft Corporation */
diff --git a/ports_smp/cortex_a34_smp/gnu/src/tx_thread_smp_current_state_get.S b/ports_smp/cortex_a34_smp/gnu/src/tx_thread_smp_current_state_get.S
index edae94d5..707b41d2 100644
--- a/ports_smp/cortex_a34_smp/gnu/src/tx_thread_smp_current_state_get.S
+++ b/ports_smp/cortex_a34_smp/gnu/src/tx_thread_smp_current_state_get.S
@@ -19,7 +19,9 @@
/** */
/**************************************************************************/
/**************************************************************************/
-
+#ifdef TX_INCLUDE_USER_DEFINE_FILE
+#include "tx_user.h"
+#endif
.text
.align 3
@@ -27,8 +29,8 @@
/* */
/* FUNCTION RELEASE */
/* */
-/* _tx_thread_smp_current_state_get Cortex-A35-SMP/AC6 */
-/* 6.1.10 */
+/* _tx_thread_smp_current_state_get ARMv8-A-SMP */
+/* 6.3.0 */
/* AUTHOR */
/* */
/* William E. Lamie, Microsoft Corporation */
diff --git a/ports_smp/cortex_a34_smp/gnu/src/tx_thread_smp_current_thread_get.S b/ports_smp/cortex_a34_smp/gnu/src/tx_thread_smp_current_thread_get.S
index dd740e05..6c4bc9af 100644
--- a/ports_smp/cortex_a34_smp/gnu/src/tx_thread_smp_current_thread_get.S
+++ b/ports_smp/cortex_a34_smp/gnu/src/tx_thread_smp_current_thread_get.S
@@ -19,7 +19,9 @@
/** */
/**************************************************************************/
/**************************************************************************/
-
+#ifdef TX_INCLUDE_USER_DEFINE_FILE
+#include "tx_user.h"
+#endif
.text
.align 3
@@ -27,8 +29,8 @@
/* */
/* FUNCTION RELEASE */
/* */
-/* _tx_thread_smp_current_thread_get Cortex-A35-SMP/AC6 */
-/* 6.1.10 */
+/* _tx_thread_smp_current_thread_get ARMv8-A-SMP */
+/* 6.3.0 */
/* AUTHOR */
/* */
/* William E. Lamie, Microsoft Corporation */
diff --git a/ports_smp/cortex_a34_smp/gnu/src/tx_thread_smp_initialize_wait.S b/ports_smp/cortex_a34_smp/gnu/src/tx_thread_smp_initialize_wait.S
index 985136b5..defd791c 100644
--- a/ports_smp/cortex_a34_smp/gnu/src/tx_thread_smp_initialize_wait.S
+++ b/ports_smp/cortex_a34_smp/gnu/src/tx_thread_smp_initialize_wait.S
@@ -19,7 +19,9 @@
/** */
/**************************************************************************/
/**************************************************************************/
-
+#ifdef TX_INCLUDE_USER_DEFINE_FILE
+#include "tx_user.h"
+#endif
.text
.align 3
@@ -27,8 +29,8 @@
/* */
/* FUNCTION RELEASE */
/* */
-/* _tx_thread_smp_initialize_wait Cortex-A35-SMP/AC6 */
-/* 6.1.10 */
+/* _tx_thread_smp_initialize_wait ARMv8-A-SMP */
+/* 6.3.0 */
/* AUTHOR */
/* */
/* William E. Lamie, Microsoft Corporation */
diff --git a/ports_smp/cortex_a34_smp/gnu/src/tx_thread_smp_low_level_initialize.S b/ports_smp/cortex_a34_smp/gnu/src/tx_thread_smp_low_level_initialize.S
index 64b854d0..99b20d24 100644
--- a/ports_smp/cortex_a34_smp/gnu/src/tx_thread_smp_low_level_initialize.S
+++ b/ports_smp/cortex_a34_smp/gnu/src/tx_thread_smp_low_level_initialize.S
@@ -19,7 +19,9 @@
/** */
/**************************************************************************/
/**************************************************************************/
-
+#ifdef TX_INCLUDE_USER_DEFINE_FILE
+#include "tx_user.h"
+#endif
.text
.align 3
@@ -27,8 +29,8 @@
/* */
/* FUNCTION RELEASE */
/* */
-/* _tx_thread_smp_low_level_initialize Cortex-A35-SMP/AC6 */
-/* 6.1.10 */
+/* _tx_thread_smp_low_level_initialize ARMv8-A-SMP */
+/* 6.3.0 */
/* AUTHOR */
/* */
/* William E. Lamie, Microsoft Corporation */
diff --git a/ports_smp/cortex_a34_smp/gnu/src/tx_thread_smp_protect.S b/ports_smp/cortex_a34_smp/gnu/src/tx_thread_smp_protect.S
index 4a48c56c..1155a3fa 100644
--- a/ports_smp/cortex_a34_smp/gnu/src/tx_thread_smp_protect.S
+++ b/ports_smp/cortex_a34_smp/gnu/src/tx_thread_smp_protect.S
@@ -19,7 +19,9 @@
/** */
/**************************************************************************/
/**************************************************************************/
-
+#ifdef TX_INCLUDE_USER_DEFINE_FILE
+#include "tx_user.h"
+#endif
/* Include macros for modifying the wait list. */
#include "tx_thread_smp_protection_wait_list_macros.h"
@@ -31,8 +33,8 @@
/* */
/* FUNCTION RELEASE */
/* */
-/* _tx_thread_smp_protect Cortex-A35-SMP/AC6 */
-/* 6.1.11 */
+/* _tx_thread_smp_protect ARMv8-A-SMP */
+/* 6.3.0 */
/* AUTHOR */
/* */
/* William E. Lamie, Microsoft Corporation */
diff --git a/ports_smp/cortex_a34_smp/gnu/src/tx_thread_smp_time_get.S b/ports_smp/cortex_a34_smp/gnu/src/tx_thread_smp_time_get.S
index f3045738..4bb9f1cb 100644
--- a/ports_smp/cortex_a34_smp/gnu/src/tx_thread_smp_time_get.S
+++ b/ports_smp/cortex_a34_smp/gnu/src/tx_thread_smp_time_get.S
@@ -9,6 +9,7 @@
* SPDX-License-Identifier: MIT
**************************************************************************/
+// Portions of this file were generated with AI assistance.
/**************************************************************************/
/**************************************************************************/
@@ -19,7 +20,9 @@
/** */
/**************************************************************************/
/**************************************************************************/
-
+#ifdef TX_INCLUDE_USER_DEFINE_FILE
+#include "tx_user.h"
+#endif
.text
.align 3
@@ -27,8 +30,8 @@
/* */
/* FUNCTION RELEASE */
/* */
-/* _tx_thread_smp_time_get Cortex-A35-SMP/AC6 */
-/* 6.1.10 */
+/* _tx_thread_smp_time_get ARMv8-A-SMP */
+/* 6.3.0 */
/* AUTHOR */
/* */
/* William E. Lamie, Microsoft Corporation */
@@ -58,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_smp/cortex_a34_smp/gnu/src/tx_thread_smp_unprotect.S b/ports_smp/cortex_a34_smp/gnu/src/tx_thread_smp_unprotect.S
index 4b5bd9a2..680e8bc8 100644
--- a/ports_smp/cortex_a34_smp/gnu/src/tx_thread_smp_unprotect.S
+++ b/ports_smp/cortex_a34_smp/gnu/src/tx_thread_smp_unprotect.S
@@ -19,7 +19,9 @@
/** */
/**************************************************************************/
/**************************************************************************/
-
+#ifdef TX_INCLUDE_USER_DEFINE_FILE
+#include "tx_user.h"
+#endif
.text
.align 3
@@ -27,8 +29,8 @@
/* */
/* FUNCTION RELEASE */
/* */
-/* _tx_thread_smp_unprotect Cortex-A35-SMP/AC6 */
-/* 6.1.11 */
+/* _tx_thread_smp_unprotect ARMv8-A-SMP */
+/* 6.3.0 */
/* AUTHOR */
/* */
/* William E. Lamie, Microsoft Corporation */
diff --git a/ports_smp/cortex_a34_smp/gnu/src/tx_thread_stack_build.S b/ports_smp/cortex_a34_smp/gnu/src/tx_thread_stack_build.S
index fa11a65c..581e259e 100644
--- a/ports_smp/cortex_a34_smp/gnu/src/tx_thread_stack_build.S
+++ b/ports_smp/cortex_a34_smp/gnu/src/tx_thread_stack_build.S
@@ -19,7 +19,9 @@
/** */
/**************************************************************************/
/**************************************************************************/
-
+#ifdef TX_INCLUDE_USER_DEFINE_FILE
+#include "tx_user.h"
+#endif
.text
.align 3
@@ -28,7 +30,7 @@
/* FUNCTION RELEASE */
/* */
/* _tx_thread_stack_build ARMv8-A-SMP */
-/* 6.1.10 */
+/* 6.3.0 */
/* AUTHOR */
/* */
/* William E. Lamie, Microsoft Corporation */
diff --git a/ports_smp/cortex_a34_smp/gnu/src/tx_thread_system_return.S b/ports_smp/cortex_a34_smp/gnu/src/tx_thread_system_return.S
index 4eebb9aa..23c75241 100644
--- a/ports_smp/cortex_a34_smp/gnu/src/tx_thread_system_return.S
+++ b/ports_smp/cortex_a34_smp/gnu/src/tx_thread_system_return.S
@@ -19,7 +19,9 @@
/** */
/**************************************************************************/
/**************************************************************************/
-
+#ifdef TX_INCLUDE_USER_DEFINE_FILE
+#include "tx_user.h"
+#endif
.text
.align 3
@@ -28,7 +30,7 @@
/* FUNCTION RELEASE */
/* */
/* _tx_thread_system_return ARMv8-A-SMP */
-/* 6.1.10 */
+/* 6.3.0 */
/* AUTHOR */
/* */
/* William E. Lamie, Microsoft Corporation */
@@ -159,6 +161,7 @@ __tx_thread_dont_save_ts:
/* Set ready bit in thread control block. */
+ DMB ISH // Ensure that accesses to shared resource have completed
MOV x3, #1 // Build ready value
STR w3, [x6, #260] // Make the thread ready
DMB ISH //
diff --git a/ports_smp/cortex_a34_smp/gnu/src/tx_timer_interrupt.S b/ports_smp/cortex_a34_smp/gnu/src/tx_timer_interrupt.S
index 6f90e5d1..5c6a6bc2 100644
--- a/ports_smp/cortex_a34_smp/gnu/src/tx_timer_interrupt.S
+++ b/ports_smp/cortex_a34_smp/gnu/src/tx_timer_interrupt.S
@@ -19,7 +19,9 @@
/** */
/**************************************************************************/
/**************************************************************************/
-
+#ifdef TX_INCLUDE_USER_DEFINE_FILE
+#include "tx_user.h"
+#endif
.text
.align 3
@@ -28,7 +30,7 @@
/* FUNCTION RELEASE */
/* */
/* _tx_timer_interrupt ARMv8-A-SMP */
-/* 6.1.10 */
+/* 6.3.0 */
/* AUTHOR */
/* */
/* William E. Lamie, Microsoft Corporation */
diff --git a/ports_smp/cortex_a35_smp/ac6/example_build/sample_threadx/sample_threadx.launch b/ports_smp/cortex_a35_smp/ac6/example_build/sample_threadx/sample_threadx.launch
index 5a0bdcf4..639e2f4e 100644
--- a/ports_smp/cortex_a35_smp/ac6/example_build/sample_threadx/sample_threadx.launch
+++ b/ports_smp/cortex_a35_smp/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_smp/cortex_a35_smp/ac6/inc/tx_port.h b/ports_smp/cortex_a35_smp/ac6/inc/tx_port.h
index e97d78d5..38c86cb2 100644
--- a/ports_smp/cortex_a35_smp/ac6/inc/tx_port.h
+++ b/ports_smp/cortex_a35_smp/ac6/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_smp/cortex_a35_smp/ac6/src/tx_thread_smp_time_get.S b/ports_smp/cortex_a35_smp/ac6/src/tx_thread_smp_time_get.S
index 335824fb..4bb9f1cb 100644
--- a/ports_smp/cortex_a35_smp/ac6/src/tx_thread_smp_time_get.S
+++ b/ports_smp/cortex_a35_smp/ac6/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_smp/cortex_a35_smp/gnu/CMakeLists.txt b/ports_smp/cortex_a35_smp/gnu/CMakeLists.txt
new file mode 100644
index 00000000..36f7492b
--- /dev/null
+++ b/ports_smp/cortex_a35_smp/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_smp/cortex_a35_smp/gnu/example_build/build_threadx.sh b/ports_smp/cortex_a35_smp/gnu/example_build/build_threadx.sh
new file mode 100755
index 00000000..b3b2cd36
--- /dev/null
+++ b/ports_smp/cortex_a35_smp/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_smp/cortex_a35_smp/gnu/example_build/build_threadx_sample.sh b/ports_smp/cortex_a35_smp/gnu/example_build/build_threadx_sample.sh
new file mode 100755
index 00000000..94248a88
--- /dev/null
+++ b/ports_smp/cortex_a35_smp/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_smp/cortex_a35_smp/gnu/example_build/readme.md b/ports_smp/cortex_a35_smp/gnu/example_build/readme.md
new file mode 100644
index 00000000..3c52a7da
--- /dev/null
+++ b/ports_smp/cortex_a35_smp/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_smp/cortex_a35_smp/gnu/example_build/sample_threadx/sample_threadx.launch b/ports_smp/cortex_a35_smp/gnu/example_build/sample_threadx/sample_threadx.launch
index d583631e..d06144eb 100644
--- a/ports_smp/cortex_a35_smp/gnu/example_build/sample_threadx/sample_threadx.launch
+++ b/ports_smp/cortex_a35_smp/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_smp/cortex_a35_smp/gnu/example_build/sample_threadx/semihost_stub.S b/ports_smp/cortex_a35_smp/gnu/example_build/sample_threadx/semihost_stub.S
new file mode 100644
index 00000000..c456875d
--- /dev/null
+++ b/ports_smp/cortex_a35_smp/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_smp/cortex_a35_smp/gnu/inc/tx_port.h b/ports_smp/cortex_a35_smp/gnu/inc/tx_port.h
index e97d78d5..38c86cb2 100644
--- a/ports_smp/cortex_a35_smp/gnu/inc/tx_port.h
+++ b/ports_smp/cortex_a35_smp/gnu/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_smp/cortex_a35_smp/gnu/src/tx_thread_smp_time_get.S b/ports_smp/cortex_a35_smp/gnu/src/tx_thread_smp_time_get.S
index 335824fb..4bb9f1cb 100644
--- a/ports_smp/cortex_a35_smp/gnu/src/tx_thread_smp_time_get.S
+++ b/ports_smp/cortex_a35_smp/gnu/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_smp/cortex_a53_smp/ac6/example_build/sample_threadx/sample_threadx.launch b/ports_smp/cortex_a53_smp/ac6/example_build/sample_threadx/sample_threadx.launch
index 27743868..dc48da27 100644
--- a/ports_smp/cortex_a53_smp/ac6/example_build/sample_threadx/sample_threadx.launch
+++ b/ports_smp/cortex_a53_smp/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;"/>
@@ -316,13 +309,13 @@
<listAttribute key="com.arm.debugger.views.common.AddressTracker.debugger.view.DisassemblyView.ranges">
<listEntry value="100"/>
</listAttribute>
- <stringAttribute key="config_db_activity_name" value="Cortex-A35x4 SMP"/>
+ <stringAttribute key="config_db_activity_name" value="Cortex-A53x4 SMP"/>
<stringAttribute key="config_db_connection_keys" value="dtsl_config dtsl_tracecapture_option connect_existing_model dtsl_config_script model_params model_iris config_file model_connection_address setup TCP_KILL_ON_EXIT TCP_DISABLE_EXTENDED_MODE"/>
<stringAttribute key="config_db_connection_type" value="Bare Metal Debug"/>
<stringAttribute key="config_db_platform_name" value="Arm FVP - Base_A53x4"/>
<stringAttribute key="config_db_project_type" value="Bare Metal Debug"/>
<stringAttribute key="config_db_project_type_id" value="BARE_METAL"/>
- <stringAttribute key="config_db_taxonomy_id" value="/platform/armfvp/base_a35x4"/>
+ <stringAttribute key="config_db_taxonomy_id" value="/platform/armfvp/base_a53x4"/>
<stringAttribute key="config_file" value="CDB://iris_config.xml"/>
<booleanAttribute key="connectOnly" value="false"/>
<stringAttribute key="connect_existing_model" value="false"/>
@@ -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-A53x4&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_smp/cortex_a53_smp/ac6/inc/tx_port.h b/ports_smp/cortex_a53_smp/ac6/inc/tx_port.h
index e97d78d5..38c86cb2 100644
--- a/ports_smp/cortex_a53_smp/ac6/inc/tx_port.h
+++ b/ports_smp/cortex_a53_smp/ac6/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_smp/cortex_a53_smp/ac6/src/tx_thread_smp_time_get.S b/ports_smp/cortex_a53_smp/ac6/src/tx_thread_smp_time_get.S
index 335824fb..4bb9f1cb 100644
--- a/ports_smp/cortex_a53_smp/ac6/src/tx_thread_smp_time_get.S
+++ b/ports_smp/cortex_a53_smp/ac6/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_smp/cortex_a53_smp/gnu/CMakeLists.txt b/ports_smp/cortex_a53_smp/gnu/CMakeLists.txt
new file mode 100644
index 00000000..36f7492b
--- /dev/null
+++ b/ports_smp/cortex_a53_smp/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_smp/cortex_a53_smp/gnu/example_build/build_threadx.sh b/ports_smp/cortex_a53_smp/gnu/example_build/build_threadx.sh
new file mode 100755
index 00000000..b3b2cd36
--- /dev/null
+++ b/ports_smp/cortex_a53_smp/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_smp/cortex_a53_smp/gnu/example_build/build_threadx_sample.sh b/ports_smp/cortex_a53_smp/gnu/example_build/build_threadx_sample.sh
new file mode 100755
index 00000000..94248a88
--- /dev/null
+++ b/ports_smp/cortex_a53_smp/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_smp/cortex_a53_smp/gnu/example_build/readme.md b/ports_smp/cortex_a53_smp/gnu/example_build/readme.md
new file mode 100644
index 00000000..3c52a7da
--- /dev/null
+++ b/ports_smp/cortex_a53_smp/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_smp/cortex_a53_smp/gnu/example_build/sample_threadx/sample_threadx.launch b/ports_smp/cortex_a53_smp/gnu/example_build/sample_threadx/sample_threadx.launch
index d0fd074c..34ec164b 100644
--- a/ports_smp/cortex_a53_smp/gnu/example_build/sample_threadx/sample_threadx.launch
+++ b/ports_smp/cortex_a53_smp/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"/>
@@ -345,13 +338,13 @@
<listAttribute key="com.arm.debugger.views.common.AddressTracker.debugger.view.DisassemblyView.ranges">
<listEntry value="100"/>
</listAttribute>
- <stringAttribute key="config_db_activity_name" value="Cortex-A35x4 SMP"/>
+ <stringAttribute key="config_db_activity_name" value="Cortex-A53x4 SMP"/>
<stringAttribute key="config_db_connection_keys" value="dtsl_config dtsl_tracecapture_option connect_existing_model dtsl_config_script model_params model_iris config_file model_connection_address setup TCP_KILL_ON_EXIT TCP_DISABLE_EXTENDED_MODE"/>
<stringAttribute key="config_db_connection_type" value="Bare Metal Debug"/>
<stringAttribute key="config_db_platform_name" value="Arm FVP - Base_A53x4"/>
<stringAttribute key="config_db_project_type" value="Bare Metal Debug"/>
<stringAttribute key="config_db_project_type_id" value="BARE_METAL"/>
- <stringAttribute key="config_db_taxonomy_id" value="/platform/armfvp/base_a35x4"/>
+ <stringAttribute key="config_db_taxonomy_id" value="/platform/armfvp/base_a53x4"/>
<stringAttribute key="config_file" value="CDB://iris_config.xml"/>
<booleanAttribute key="connectOnly" value="false"/>
<stringAttribute key="connect_existing_model" value="false"/>
@@ -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-A53x4&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_smp/cortex_a53_smp/gnu/example_build/sample_threadx/semihost_stub.S b/ports_smp/cortex_a53_smp/gnu/example_build/sample_threadx/semihost_stub.S
new file mode 100644
index 00000000..c456875d
--- /dev/null
+++ b/ports_smp/cortex_a53_smp/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_smp/cortex_a53_smp/gnu/inc/tx_port.h b/ports_smp/cortex_a53_smp/gnu/inc/tx_port.h
index e97d78d5..38c86cb2 100644
--- a/ports_smp/cortex_a53_smp/gnu/inc/tx_port.h
+++ b/ports_smp/cortex_a53_smp/gnu/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_smp/cortex_a53_smp/gnu/src/tx_thread_smp_time_get.S b/ports_smp/cortex_a53_smp/gnu/src/tx_thread_smp_time_get.S
index 335824fb..4bb9f1cb 100644
--- a/ports_smp/cortex_a53_smp/gnu/src/tx_thread_smp_time_get.S
+++ b/ports_smp/cortex_a53_smp/gnu/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_smp/cortex_a55_smp/ac6/example_build/sample_threadx/sample_threadx.launch b/ports_smp/cortex_a55_smp/ac6/example_build/sample_threadx/sample_threadx.launch
index f642a3e4..4b336147 100644
--- a/ports_smp/cortex_a55_smp/ac6/example_build/sample_threadx/sample_threadx.launch
+++ b/ports_smp/cortex_a55_smp/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;"/>
@@ -316,13 +309,13 @@
<listAttribute key="com.arm.debugger.views.common.AddressTracker.debugger.view.DisassemblyView.ranges">
<listEntry value="100"/>
</listAttribute>
- <stringAttribute key="config_db_activity_name" value="Cortex-A35x4 SMP"/>
+ <stringAttribute key="config_db_activity_name" value="Cortex-A55x4 SMP"/>
<stringAttribute key="config_db_connection_keys" value="dtsl_config dtsl_tracecapture_option connect_existing_model dtsl_config_script model_params model_iris config_file model_connection_address setup TCP_KILL_ON_EXIT TCP_DISABLE_EXTENDED_MODE"/>
<stringAttribute key="config_db_connection_type" value="Bare Metal Debug"/>
<stringAttribute key="config_db_platform_name" value="Arm FVP - Base_A55x4"/>
<stringAttribute key="config_db_project_type" value="Bare Metal Debug"/>
<stringAttribute key="config_db_project_type_id" value="BARE_METAL"/>
- <stringAttribute key="config_db_taxonomy_id" value="/platform/armfvp/base_a35x4"/>
+ <stringAttribute key="config_db_taxonomy_id" value="/platform/armfvp/base_a55x4"/>
<stringAttribute key="config_file" value="CDB://iris_config.xml"/>
<booleanAttribute key="connectOnly" value="false"/>
<stringAttribute key="connect_existing_model" value="false"/>
@@ -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-A55x4&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_smp/cortex_a55_smp/ac6/inc/tx_port.h b/ports_smp/cortex_a55_smp/ac6/inc/tx_port.h
index e97d78d5..38c86cb2 100644
--- a/ports_smp/cortex_a55_smp/ac6/inc/tx_port.h
+++ b/ports_smp/cortex_a55_smp/ac6/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_smp/cortex_a55_smp/ac6/src/tx_thread_smp_time_get.S b/ports_smp/cortex_a55_smp/ac6/src/tx_thread_smp_time_get.S
index 335824fb..4bb9f1cb 100644
--- a/ports_smp/cortex_a55_smp/ac6/src/tx_thread_smp_time_get.S
+++ b/ports_smp/cortex_a55_smp/ac6/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_smp/cortex_a55_smp/gnu/CMakeLists.txt b/ports_smp/cortex_a55_smp/gnu/CMakeLists.txt
new file mode 100644
index 00000000..36f7492b
--- /dev/null
+++ b/ports_smp/cortex_a55_smp/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_smp/cortex_a55_smp/gnu/example_build/build_threadx.sh b/ports_smp/cortex_a55_smp/gnu/example_build/build_threadx.sh
new file mode 100755
index 00000000..b3b2cd36
--- /dev/null
+++ b/ports_smp/cortex_a55_smp/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_smp/cortex_a55_smp/gnu/example_build/build_threadx_sample.sh b/ports_smp/cortex_a55_smp/gnu/example_build/build_threadx_sample.sh
new file mode 100755
index 00000000..94248a88
--- /dev/null
+++ b/ports_smp/cortex_a55_smp/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_smp/cortex_a55_smp/gnu/example_build/readme.md b/ports_smp/cortex_a55_smp/gnu/example_build/readme.md
new file mode 100644
index 00000000..3c52a7da
--- /dev/null
+++ b/ports_smp/cortex_a55_smp/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_smp/cortex_a55_smp/gnu/example_build/sample_threadx/sample_threadx.launch b/ports_smp/cortex_a55_smp/gnu/example_build/sample_threadx/sample_threadx.launch
index 2f22ba75..2ad35b44 100644
--- a/ports_smp/cortex_a55_smp/gnu/example_build/sample_threadx/sample_threadx.launch
+++ b/ports_smp/cortex_a55_smp/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"/>
@@ -345,13 +338,13 @@
<listAttribute key="com.arm.debugger.views.common.AddressTracker.debugger.view.DisassemblyView.ranges">
<listEntry value="100"/>
</listAttribute>
- <stringAttribute key="config_db_activity_name" value="Cortex-A35x4 SMP"/>
+ <stringAttribute key="config_db_activity_name" value="Cortex-A55x4 SMP"/>
<stringAttribute key="config_db_connection_keys" value="dtsl_config dtsl_tracecapture_option connect_existing_model dtsl_config_script model_params model_iris config_file model_connection_address setup TCP_KILL_ON_EXIT TCP_DISABLE_EXTENDED_MODE"/>
<stringAttribute key="config_db_connection_type" value="Bare Metal Debug"/>
<stringAttribute key="config_db_platform_name" value="Arm FVP - Base_A55x4"/>
<stringAttribute key="config_db_project_type" value="Bare Metal Debug"/>
<stringAttribute key="config_db_project_type_id" value="BARE_METAL"/>
- <stringAttribute key="config_db_taxonomy_id" value="/platform/armfvp/base_a35x4"/>
+ <stringAttribute key="config_db_taxonomy_id" value="/platform/armfvp/base_a55x4"/>
<stringAttribute key="config_file" value="CDB://iris_config.xml"/>
<booleanAttribute key="connectOnly" value="false"/>
<stringAttribute key="connect_existing_model" value="false"/>
@@ -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-A55x4&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_smp/cortex_a55_smp/gnu/example_build/sample_threadx/semihost_stub.S b/ports_smp/cortex_a55_smp/gnu/example_build/sample_threadx/semihost_stub.S
new file mode 100644
index 00000000..c456875d
--- /dev/null
+++ b/ports_smp/cortex_a55_smp/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_smp/cortex_a55_smp/gnu/inc/tx_port.h b/ports_smp/cortex_a55_smp/gnu/inc/tx_port.h
index e97d78d5..38c86cb2 100644
--- a/ports_smp/cortex_a55_smp/gnu/inc/tx_port.h
+++ b/ports_smp/cortex_a55_smp/gnu/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_smp/cortex_a55_smp/gnu/src/tx_thread_smp_time_get.S b/ports_smp/cortex_a55_smp/gnu/src/tx_thread_smp_time_get.S
index 335824fb..4bb9f1cb 100644
--- a/ports_smp/cortex_a55_smp/gnu/src/tx_thread_smp_time_get.S
+++ b/ports_smp/cortex_a55_smp/gnu/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_smp/cortex_a57_smp/ac6/example_build/sample_threadx/sample_threadx.launch b/ports_smp/cortex_a57_smp/ac6/example_build/sample_threadx/sample_threadx.launch
index 674e9663..fb3877c6 100644
--- a/ports_smp/cortex_a57_smp/ac6/example_build/sample_threadx/sample_threadx.launch
+++ b/ports_smp/cortex_a57_smp/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;"/>
@@ -316,13 +309,13 @@
<listAttribute key="com.arm.debugger.views.common.AddressTracker.debugger.view.DisassemblyView.ranges">
<listEntry value="100"/>
</listAttribute>
- <stringAttribute key="config_db_activity_name" value="Cortex-A35x4 SMP"/>
+ <stringAttribute key="config_db_activity_name" value="Cortex-A57x4 SMP"/>
<stringAttribute key="config_db_connection_keys" value="dtsl_config dtsl_tracecapture_option connect_existing_model dtsl_config_script model_params model_iris config_file model_connection_address setup TCP_KILL_ON_EXIT TCP_DISABLE_EXTENDED_MODE"/>
<stringAttribute key="config_db_connection_type" value="Bare Metal Debug"/>
<stringAttribute key="config_db_platform_name" value="Arm FVP - Base_A57x4"/>
<stringAttribute key="config_db_project_type" value="Bare Metal Debug"/>
<stringAttribute key="config_db_project_type_id" value="BARE_METAL"/>
- <stringAttribute key="config_db_taxonomy_id" value="/platform/armfvp/base_a35x4"/>
+ <stringAttribute key="config_db_taxonomy_id" value="/platform/armfvp/base_a57x4"/>
<stringAttribute key="config_file" value="CDB://iris_config.xml"/>
<booleanAttribute key="connectOnly" value="false"/>
<stringAttribute key="connect_existing_model" value="false"/>
@@ -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-A57x4&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_smp/cortex_a57_smp/ac6/inc/tx_port.h b/ports_smp/cortex_a57_smp/ac6/inc/tx_port.h
index e97d78d5..38c86cb2 100644
--- a/ports_smp/cortex_a57_smp/ac6/inc/tx_port.h
+++ b/ports_smp/cortex_a57_smp/ac6/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_smp/cortex_a57_smp/ac6/src/tx_thread_smp_time_get.S b/ports_smp/cortex_a57_smp/ac6/src/tx_thread_smp_time_get.S
index 335824fb..4bb9f1cb 100644
--- a/ports_smp/cortex_a57_smp/ac6/src/tx_thread_smp_time_get.S
+++ b/ports_smp/cortex_a57_smp/ac6/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_smp/cortex_a57_smp/gnu/CMakeLists.txt b/ports_smp/cortex_a57_smp/gnu/CMakeLists.txt
new file mode 100644
index 00000000..36f7492b
--- /dev/null
+++ b/ports_smp/cortex_a57_smp/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_smp/cortex_a57_smp/gnu/example_build/build_threadx.sh b/ports_smp/cortex_a57_smp/gnu/example_build/build_threadx.sh
new file mode 100755
index 00000000..b3b2cd36
--- /dev/null
+++ b/ports_smp/cortex_a57_smp/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_smp/cortex_a57_smp/gnu/example_build/build_threadx_sample.sh b/ports_smp/cortex_a57_smp/gnu/example_build/build_threadx_sample.sh
new file mode 100755
index 00000000..94248a88
--- /dev/null
+++ b/ports_smp/cortex_a57_smp/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_smp/cortex_a57_smp/gnu/example_build/readme.md b/ports_smp/cortex_a57_smp/gnu/example_build/readme.md
new file mode 100644
index 00000000..3c52a7da
--- /dev/null
+++ b/ports_smp/cortex_a57_smp/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_smp/cortex_a57_smp/gnu/example_build/sample_threadx/sample_threadx.launch b/ports_smp/cortex_a57_smp/gnu/example_build/sample_threadx/sample_threadx.launch
index 17c737ee..40fa00b6 100644
--- a/ports_smp/cortex_a57_smp/gnu/example_build/sample_threadx/sample_threadx.launch
+++ b/ports_smp/cortex_a57_smp/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"/>
@@ -345,13 +338,13 @@
<listAttribute key="com.arm.debugger.views.common.AddressTracker.debugger.view.DisassemblyView.ranges">
<listEntry value="100"/>
</listAttribute>
- <stringAttribute key="config_db_activity_name" value="Cortex-A35x4 SMP"/>
+ <stringAttribute key="config_db_activity_name" value="Cortex-A57x4 SMP"/>
<stringAttribute key="config_db_connection_keys" value="dtsl_config dtsl_tracecapture_option connect_existing_model dtsl_config_script model_params model_iris config_file model_connection_address setup TCP_KILL_ON_EXIT TCP_DISABLE_EXTENDED_MODE"/>
<stringAttribute key="config_db_connection_type" value="Bare Metal Debug"/>
<stringAttribute key="config_db_platform_name" value="Arm FVP - Base_A57x4"/>
<stringAttribute key="config_db_project_type" value="Bare Metal Debug"/>
<stringAttribute key="config_db_project_type_id" value="BARE_METAL"/>
- <stringAttribute key="config_db_taxonomy_id" value="/platform/armfvp/base_a35x4"/>
+ <stringAttribute key="config_db_taxonomy_id" value="/platform/armfvp/base_a57x4"/>
<stringAttribute key="config_file" value="CDB://iris_config.xml"/>
<booleanAttribute key="connectOnly" value="false"/>
<stringAttribute key="connect_existing_model" value="false"/>
@@ -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-A57x4&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_smp/cortex_a57_smp/gnu/example_build/sample_threadx/semihost_stub.S b/ports_smp/cortex_a57_smp/gnu/example_build/sample_threadx/semihost_stub.S
new file mode 100644
index 00000000..c456875d
--- /dev/null
+++ b/ports_smp/cortex_a57_smp/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_smp/cortex_a57_smp/gnu/inc/tx_port.h b/ports_smp/cortex_a57_smp/gnu/inc/tx_port.h
index e97d78d5..38c86cb2 100644
--- a/ports_smp/cortex_a57_smp/gnu/inc/tx_port.h
+++ b/ports_smp/cortex_a57_smp/gnu/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_smp/cortex_a57_smp/gnu/src/tx_thread_smp_time_get.S b/ports_smp/cortex_a57_smp/gnu/src/tx_thread_smp_time_get.S
index 335824fb..4bb9f1cb 100644
--- a/ports_smp/cortex_a57_smp/gnu/src/tx_thread_smp_time_get.S
+++ b/ports_smp/cortex_a57_smp/gnu/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_smp/cortex_a5_smp/ac5/inc/tx_port.h b/ports_smp/cortex_a5_smp/ac5/inc/tx_port.h
index 0db5a292..30e2719a 100644
--- a/ports_smp/cortex_a5_smp/ac5/inc/tx_port.h
+++ b/ports_smp/cortex_a5_smp/ac5/inc/tx_port.h
@@ -388,7 +388,7 @@ void tx_thread_vfp_disable(void);
#ifdef TX_THREAD_INIT
CHAR _tx_version_id[] =
- "(c) 2024 Microsoft Corp. (c) 2026-present Eclipse ThreadX contributors. * ThreadX SMP/Cortex-A5/AC5 Version 6.5.1.202602a *";
+ "(c) 2024 Microsoft Corp. (c) 2026-present Eclipse ThreadX contributors. * ThreadX SMP/Cortex-A5/AC5 Version 6.5.2.202603 *";
#else
extern CHAR _tx_version_id[];
#endif
diff --git a/ports_smp/cortex_a5_smp/ac5/src/tx_thread_context_restore.s b/ports_smp/cortex_a5_smp/ac5/src/tx_thread_context_restore.s
index 21d63d05..a3ca9ad7 100644
--- a/ports_smp/cortex_a5_smp/ac5/src/tx_thread_context_restore.s
+++ b/ports_smp/cortex_a5_smp/ac5/src/tx_thread_context_restore.s
@@ -1,5 +1,6 @@
;/***************************************************************************
; * Copyright (c) 2024 Microsoft Corporation
+; * 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
@@ -7,6 +8,7 @@
; *
; * SPDX-License-Identifier: MIT
; **************************************************************************/
+; Portions of this file were generated with AI assistance.
;
;
;/**************************************************************************/
@@ -29,8 +31,6 @@
;#include "tx_thread.h"
;#include "tx_timer.h"
;
-;/* Include macros for modifying the wait list. */
-#include "tx_thread_smp_protection_wait_list_macros.h"
IF :DEF:TX_ENABLE_FIQ_SUPPORT
DISABLE_INTS EQU 0xC0 ; Disable IRQ & FIQ interrupts
@@ -51,11 +51,6 @@ SVC_MODE EQU 0x93 ; SVC mode
IMPORT _tx_thread_preempt_disable
IMPORT _tx_timer_interrupt_active
IMPORT _tx_thread_smp_protection
- IMPORT _tx_thread_smp_protect_wait_counts
- IMPORT _tx_thread_smp_protect_wait_list
- IMPORT _tx_thread_smp_protect_wait_list_lock_protect_in_force
- IMPORT _tx_thread_smp_protect_wait_list_tail
- IMPORT _tx_thread_smp_protect_wait_list_size
IF :DEF:TX_ENABLE_EXECUTION_CHANGE_NOTIFY
IMPORT _tx_execution_isr_exit
ENDIF
@@ -196,77 +191,6 @@ __tx_thread_no_preempt_restore
; {
;
__tx_thread_preempt_restore
-;
-; /* Was the thread being preempted waiting for the lock? */
-; if (_tx_thread_smp_protect_wait_counts[this_core] != 0)
-; {
-;
- LDR r1, =_tx_thread_smp_protect_wait_counts ; Load waiting count list
- LDR r2, [r1, r10, LSL #2] ; Load waiting value for this core
- CMP r2, #0
- BEQ _nobody_waiting_for_lock ; Is the core waiting for the lock?
-;
-; /* Do we not have the lock? This means the ISR never got the inter-core lock. */
-; if (_tx_thread_smp_protection.tx_thread_smp_protect_owned != this_core)
-; {
-;
- LDR r1, =_tx_thread_smp_protection ; Load address of protection structure
- LDR r2, [r1, #8] ; Pickup the owning core
- CMP r10, r2 ; Compare our core to the owning core
- BEQ _this_core_has_lock ; Do we have the lock?
-;
-; /* We don't have the lock. This core should be in the list. Remove it. */
-; _tx_thread_smp_protect_wait_list_remove(this_core);
-;
- MOV r0, r10 ; Move the core ID to r0 for the macro
-macro_call0 _tx_thread_smp_protect_wait_list_remove ; Call macro to remove core from the list
- B _nobody_waiting_for_lock ; Leave
-;
-; }
-; else
-; {
-; /* We have the lock. This means the ISR got the inter-core lock, but
-; never released it because it saw that there was someone waiting.
-; Note this core is not in the list. */
-;
-_this_core_has_lock
-;
-; /* We're no longer waiting. Note that this should be zero since this happens during thread preemption. */
-; _tx_thread_smp_protect_wait_counts[core]--;
-;
- LDR r1, =_tx_thread_smp_protect_wait_counts ; Load waiting count list
- LDR r2, [r1, r10, LSL #2] ; Load waiting value for this core
- SUB r2, r2, #1 ; Decrement waiting value. Should be zero now
- STR r2, [r1, r10, LSL #2] ; Store new waiting value
-;
-; /* Now release the inter-core lock. */
-;
-; /* Set protected core as invalid. */
-; _tx_thread_smp_protection.tx_thread_smp_protect_core = 0xFFFFFFFF;
-;
- LDR r1, =_tx_thread_smp_protection ; Load address of protection structure
- MOV r2, #0xFFFFFFFF ; Build invalid value
- STR r2, [r1, #8] ; Mark the protected core as invalid
- DMB ; Ensure that accesses to shared resource have completed
-;
-; /* Release protection. */
-; _tx_thread_smp_protection.tx_thread_smp_protect_in_force = 0;
-;
- MOV r2, #0 ; Build release protection value
- STR r2, [r1, #0] ; Release the protection
- DSB ISH ; To ensure update of the protection occurs before other CPUs awake
-;
-; /* Wake up waiting processors. Note interrupts are already enabled. */
-;
- IF :DEF:TX_ENABLE_WFE
- SEV ; Send event to other CPUs
- ENDIF
-;
-; }
-; }
-;
-
-_nobody_waiting_for_lock
LDMIA sp!, {r3, r10, r12, lr} ; Recover temporarily saved registers
MOV r1, lr ; Save lr (point of interrupt)
diff --git a/ports_smp/cortex_a5_smp/ac5/src/tx_thread_context_save.s b/ports_smp/cortex_a5_smp/ac5/src/tx_thread_context_save.s
index 33047893..1217a5e5 100644
--- a/ports_smp/cortex_a5_smp/ac5/src/tx_thread_context_save.s
+++ b/ports_smp/cortex_a5_smp/ac5/src/tx_thread_context_save.s
@@ -1,5 +1,6 @@
;/***************************************************************************
; * Copyright (c) 2024 Microsoft Corporation
+; * Copyright (c) 2026-present Eclipse ThreadX contributors
; *
; * This program and the accompanying materials are made available under the
; * terms of the MIT License which is available at
@@ -8,6 +9,7 @@
; * SPDX-License-Identifier: MIT
; **************************************************************************/
;
+; Portions of this file were generated with AI assistance.
;
;/**************************************************************************/
;/**************************************************************************/
@@ -145,11 +147,11 @@ __tx_thread_not_nested_save
BEQ __tx_thread_idle_system_save ; If so, interrupt occurred in
; scheduling loop - nothing needs saving!
;
-; /* Save the current stack pointer in the thread's control block. */
-; _tx_thread_current_ptr[core] -> tx_thread_stack_ptr = sp;
-;
-; /* Switch to the system stack. */
-; sp = _tx_thread_system_stack_ptr;
+; /* This routine runs in IRQ mode on this core's banked IRQ stack, which
+; serves as the system stack on this architecture, so there is no stack
+; switch to perform here. The thread's stack pointer is saved in its
+; control block by _tx_thread_context_restore, and only when the
+; interrupt results in preemption. */
;
MOV r10, #0 ; Clear stack limit
diff --git a/ports_smp/cortex_a5_smp/ac5/src/tx_thread_schedule.s b/ports_smp/cortex_a5_smp/ac5/src/tx_thread_schedule.s
index e4c232aa..b24e941e 100644
--- a/ports_smp/cortex_a5_smp/ac5/src/tx_thread_schedule.s
+++ b/ports_smp/cortex_a5_smp/ac5/src/tx_thread_schedule.s
@@ -1,5 +1,6 @@
;/***************************************************************************
; * Copyright (c) 2024 Microsoft Corporation
+; * 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
@@ -8,6 +9,8 @@
; * SPDX-License-Identifier: MIT
; **************************************************************************/
;
+; Portions of this file were generated with AI assistance.
+;
;
;/**************************************************************************/
;/**************************************************************************/
@@ -164,6 +167,7 @@ _tx_thread_ready_for_execution
LDR r2, =_tx_thread_current_ptr ; Pickup address of current thread
ADD r2, r2, r12 ; Build index into the current thread array
STR r0, [r2, #0] ; Setup current thread pointer
+ DMB ; Ensure the current thread pointer write completes
;
; /* In the time between reading the execute pointer and assigning
; it to the current pointer, the execute pointer was changed by
diff --git a/ports_smp/cortex_a5_smp/ac5/src/tx_thread_smp_protect.s b/ports_smp/cortex_a5_smp/ac5/src/tx_thread_smp_protect.s
index a7419c10..ca3eb3ea 100644
--- a/ports_smp/cortex_a5_smp/ac5/src/tx_thread_smp_protect.s
+++ b/ports_smp/cortex_a5_smp/ac5/src/tx_thread_smp_protect.s
@@ -1,5 +1,6 @@
;/***************************************************************************
; * Copyright (c) 2024 Microsoft Corporation
+; * 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
@@ -7,6 +8,7 @@
; *
; * SPDX-License-Identifier: MIT
; **************************************************************************/
+; Portions of this file were generated with AI assistance.
;
;
;/**************************************************************************/
@@ -31,17 +33,9 @@
;
;
-;/* Include macros for modifying the wait list. */
-#include "tx_thread_smp_protection_wait_list_macros.h"
IMPORT _tx_thread_current_ptr
IMPORT _tx_thread_smp_protection
- IMPORT _tx_thread_smp_protect_wait_counts
- IMPORT _tx_thread_smp_protect_wait_list
- IMPORT _tx_thread_smp_protect_wait_list_lock_protect_in_force
- IMPORT _tx_thread_smp_protect_wait_list_head
- IMPORT _tx_thread_smp_protect_wait_list_tail
- IMPORT _tx_thread_smp_protect_wait_list_size
AREA ||.text||, CODE, READONLY
PRESERVE8
@@ -80,12 +74,12 @@
;/**************************************************************************/
EXPORT _tx_thread_smp_protect
_tx_thread_smp_protect
-
- PUSH {r4-r6} ; Save registers we'll be using
+;VOID _tx_thread_smp_protect(VOID)
+;{
;
; /* Disable interrupts so we don't get preempted. */
;
- MRS r0, CPSR ; Pickup current CPSR
+ MRS r3, CPSR ; Pickup current CPSR
IF :DEF:TX_ENABLE_FIQ_SUPPORT
CPSID if ; Disable IRQ and FIQ interrupts
@@ -93,266 +87,93 @@ _tx_thread_smp_protect
CPSID i ; Disable IRQ interrupts
ENDIF
;
+; /* Pickup the CPU ID. */
+;
+ MRC p15, 0, r2, c0, c0, 5 ; Read CPU ID register
+ AND r2, r2, #0x03 ; Mask off, leaving the CPU ID field
+;
; /* Do we already have protection? */
; if (this_core == _tx_thread_smp_protection.tx_thread_smp_protect_core)
; {
;
- MRC p15, 0, r1, c0, c0, 5 ; Read CPU ID register
- AND r1, r1, #0x03 ; Mask off, leaving the CPU ID field
- LDR r2, =_tx_thread_smp_protection ; Build address to protection structure
- LDR r3, [r2, #8] ; Pickup the owning core
- CMP r1, r3 ; Is it not this core?
- BNE _protection_not_owned ; No, the protection is not already owned
-;
-; /* We already have protection. */
-;
-; /* Increment the protection count. */
-; _tx_thread_smp_protection.tx_thread_smp_protect_count++;
+ LDR r0, =_tx_thread_smp_protection ; Build address to protection structure
+ LDR r1, [r0, #8] ; Pickup the owning core
+ CMP r1, r2 ; Is it this core?
+ BEQ _owned ; Yes, the protection is already owned
;
- LDR r3, [r2, #12] ; Pickup ownership count
- ADD r3, r3, #1 ; Increment ownership count
- STR r3, [r2, #12] ; Store ownership count
- DMB
-
- B _return
-
-_protection_not_owned
+; }
;
; /* Is the lock available? */
; if (_tx_thread_smp_protection.tx_thread_smp_protect_in_force == 0)
; {
;
- LDREX r3, [r2, #0] ; Pickup the protection flag
- CMP r3, #0
- BNE _start_waiting ; No, protection not available
-;
-; /* Is the list empty? */
-; if (_tx_thread_smp_protect_wait_list_head == _tx_thread_smp_protect_wait_list_tail)
-; {
-;
- LDR r3, =_tx_thread_smp_protect_wait_list_head
- LDR r3, [r3]
- LDR r4, =_tx_thread_smp_protect_wait_list_tail
- LDR r4, [r4]
- CMP r3, r4
- BNE _list_not_empty
-;
-; /* Try to get the lock. */
-; if (write_exclusive(&_tx_thread_smp_protection.tx_thread_smp_protect_in_force, 1) == SUCCESS)
-; {
-;
- MOV r3, #1 ; Build lock value
- STREX r4, r3, [r2, #0] ; Attempt to get the protection
- CMP r4, #0
- BNE _start_waiting ; Did it fail?
-;
-; /* We got the lock! */
-; _tx_thread_smp_protect_lock_got();
-;
- DMB ; Ensure write to protection finishes
-macro_call0 _tx_thread_smp_protect_lock_got ; Call the lock got function
-
- B _return
-
-_list_not_empty
-;
-; /* Are we at the front of the list? */
-; if (this_core == _tx_thread_smp_protect_wait_list[_tx_thread_smp_protect_wait_list_head])
-; {
-;
- LDR r3, =_tx_thread_smp_protect_wait_list_head ; Get the address of the head
- LDR r3, [r3] ; Get the value of the head
- LDR r4, =_tx_thread_smp_protect_wait_list ; Get the address of the list
- LDR r4, [r4, r3, LSL #2] ; Get the value at the head index
-
- CMP r1, r4
- BNE _start_waiting
-;
-; /* Is the lock still available? */
-; if (_tx_thread_smp_protection.tx_thread_smp_protect_in_force == 0)
-; {
-;
- LDR r3, [r2, #0] ; Pickup the protection flag
- CMP r3, #0
- BNE _start_waiting ; No, protection not available
-;
-; /* Get the lock. */
-; _tx_thread_smp_protection.tx_thread_smp_protect_in_force = 1;
-;
- MOV r3, #1 ; Build lock value
- STR r3, [r2, #0] ; Store lock value
- DMB ;
-;
-; /* Got the lock. */
-; _tx_thread_smp_protect_lock_got();
-;
-macro_call1 _tx_thread_smp_protect_lock_got
-;
-; /* Remove this core from the wait list. */
-; _tx_thread_smp_protect_remove_from_front_of_list();
-;
-macro_call2 _tx_thread_smp_protect_remove_from_front_of_list
-
- B _return
-
-_start_waiting
-;
-; /* For one reason or another, we didn't get the lock. */
-;
-; /* Increment wait count. */
-; _tx_thread_smp_protect_wait_counts[this_core]++;
-;
- LDR r3, =_tx_thread_smp_protect_wait_counts ; Load wait list counts
- LDR r4, [r3, r1, LSL #2] ; Load waiting value for this core
- ADD r4, r4, #1 ; Increment wait value
- STR r4, [r3, r1, LSL #2] ; Store new wait value
-;
-; /* Have we not added ourselves to the list yet? */
-; if (_tx_thread_smp_protect_wait_counts[this_core] == 1)
-; {
-;
- CMP r4, #1
- BNE _already_in_list0 ; Is this core already waiting?
-;
-; /* Add ourselves to the list. */
-; _tx_thread_smp_protect_wait_list_add(this_core);
-;
-macro_call3 _tx_thread_smp_protect_wait_list_add ; Call macro to add ourselves to the list
+ LDREX r1, [r0] ; Pickup the protection flag
+ CMP r1, #0 ; Is it available?
+ BEQ _get_protection ; Yes, attempt to get the protection
;
; }
;
-_already_in_list0
-;
-; /* Restore interrupts. */
+; /* The protection is held elsewhere. Restore interrupts so this core can be
+; preempted while it waits, then try the whole sequence again. */
;
- MSR CPSR_c, r0 ; Restore CPSR
+ MSR CPSR_c, r3 ; Restore CPSR
IF :DEF:TX_ENABLE_WFE
WFE ; Go into standby
ENDIF
-;
-; /* We do this until we have the lock. */
-; while (1)
-; {
-;
-_try_to_get_lock
-;
-; /* Disable interrupts so we don't get preempted. */
-;
- IF :DEF:TX_ENABLE_FIQ_SUPPORT
- CPSID if ; Disable IRQ and FIQ interrupts
- ELSE
- CPSID i ; Disable IRQ interrupts
- ENDIF
+ B _tx_thread_smp_protect ; On waking, restart the protection attempt
- MRC p15, 0, r1, c0, c0, 5 ; Read CPU ID register
- AND r1, r1, #0x03 ; Mask off, leaving the CPU ID field
+_get_protection
;
-; /* Do we already have protection? */
-; if (this_core == _tx_thread_smp_protection.tx_thread_smp_protect_core)
+; /* Try to get the lock. */
+; if (write_exclusive(&_tx_thread_smp_protection.tx_thread_smp_protect_in_force, 1) == SUCCESS)
; {
;
- LDR r3, [r2, #8] ; Pickup the owning core
- CMP r3, r1 ; Is it this core?
- BEQ _got_lock_after_waiting ; Yes, the protection is already owned. This means
- ; an ISR preempted us and got protection
+ MOV r1, #1 ; Build lock value
+ STREX r2, r1, [r0] ; Attempt to get the protection
+ CMP r2, #0 ; Check whether the store succeeded (0 = success)
+ BEQ _got_protection ; Yes, we have the protection
;
; }
;
-; /* Are we at the front of the list? */
-; if (this_core == _tx_thread_smp_protect_wait_list[_tx_thread_smp_protect_wait_list_head])
-; {
+; /* Another core beat us to it. Restore interrupts and try again. */
;
- LDR r3, =_tx_thread_smp_protect_wait_list_head ; Get the address of the head
- LDR r3, [r3] ; Get the value of the head
- LDR r4, =_tx_thread_smp_protect_wait_list ; Get the address of the list
- LDR r4, [r4, r3, LSL #2] ; Get the value at the head index
+ MSR CPSR_c, r3 ; Restore CPSR
+ B _tx_thread_smp_protect ; Try the whole process again
- CMP r1, r4
- BNE _did_not_get_lock
-;
-; /* Is the lock still available? */
-; if (_tx_thread_smp_protection.tx_thread_smp_protect_in_force == 0)
-; {
-;
- LDR r3, [r2, #0] ; Pickup the protection flag
- CMP r3, #0
- BNE _did_not_get_lock ; No, protection not available
-;
-; /* Get the lock. */
-; _tx_thread_smp_protection.tx_thread_smp_protect_in_force = 1;
-;
- MOV r3, #1 ; Build lock value
- STR r3, [r2, #0] ; Store lock value
- DMB ;
+_got_protection
;
-; /* Got the lock. */
-; _tx_thread_smp_protect_lock_got();
+; /* Got the lock. Record the owning core. */
+; _tx_thread_smp_protection.tx_thread_smp_protect_core = this_core;
;
-macro_call4 _tx_thread_smp_protect_lock_got
-;
-; /* Remove this core from the wait list. */
-; _tx_thread_smp_protect_remove_from_front_of_list();
-;
-macro_call5 _tx_thread_smp_protect_remove_from_front_of_list
-
- B _got_lock_after_waiting
+ DMB ; Ensure the protection write completes before it is used
+ MRC p15, 0, r2, c0, c0, 5 ; Read CPU ID register
+ AND r2, r2, #0x03 ; Mask off, leaving the CPU ID field
+ STR r2, [r0, #8] ; Save the owning core
-_did_not_get_lock
-;
-; /* For one reason or another, we didn't get the lock. */
-;
-; /* Were we removed from the list? This can happen if we're a thread
-; and we got preempted. */
-; if (_tx_thread_smp_protect_wait_counts[this_core] == 0)
-; {
-;
- LDR r3, =_tx_thread_smp_protect_wait_counts ; Load wait list counts
- LDR r4, [r3, r1, LSL #2] ; Load waiting value for this core
- CMP r4, #0
- BNE _already_in_list1 ; Is this core already in the list?
-;
-; /* Add ourselves to the list. */
-; _tx_thread_smp_protect_wait_list_add(this_core);
-;
-macro_call6 _tx_thread_smp_protect_wait_list_add ; Call macro to add ourselves to the list
-;
-; /* Our waiting count was also reset when we were preempted. Increment it again. */
-; _tx_thread_smp_protect_wait_counts[this_core]++;
-;
- LDR r3, =_tx_thread_smp_protect_wait_counts ; Load wait list counts
- LDR r4, [r3, r1, LSL #2] ; Load waiting value for this core
- ADD r4, r4, #1 ; Increment wait value
- STR r4, [r3, r1, LSL #2] ; Store new wait value value
-;
-; }
-;
-_already_in_list1
-;
-; /* Restore interrupts and try again. */
-;
- MSR CPSR_c, r0 ; Restore CPSR
- IF :DEF:TX_ENABLE_WFE
- WFE ; Go into standby
+ IF :DEF:TX_MPCORE_DEBUG_ENABLE
+ LSL r2, r2, #2 ; Build offset to array indexes
+ LDR r1, =_tx_thread_current_ptr ; Pickup start of the current thread array
+ ADD r1, r1, r2 ; Build index into the current thread array
+ LDR r2, [r1] ; Pickup current thread for this core
+ STR r2, [r0, #4] ; Save current thread pointer
+ STR LR, [r0, #16] ; Save caller's return address
+ STR r3, [r0, #20] ; Save CPSR
ENDIF
- B _try_to_get_lock ; On waking, restart the protection attempt
-_got_lock_after_waiting
+_owned
;
-; /* We're no longer waiting. */
-; _tx_thread_smp_protect_wait_counts[this_core]--;
+; /* Increment the protection count. */
+; _tx_thread_smp_protection.tx_thread_smp_protect_count++;
;
- LDR r3, =_tx_thread_smp_protect_wait_counts ; Load waiting list
- LDR r4, [r3, r1, LSL #2] ; Load current wait value
- SUB r4, r4, #1 ; Decrement wait value
- STR r4, [r3, r1, LSL #2] ; Store new wait value value
+ LDR r1, [r0, #12] ; Pickup ownership count
+ ADD r1, r1, #1 ; Increment ownership count
+ STR r1, [r0, #12] ; Store new ownership count
+ DMB ;
+ MOV r0, r3 ; Return the previous CPSR
;
-; /* Restore link register and return. */
+;}
;
-_return
-
- POP {r4-r6} ; Restore registers
-
IF {INTER} = {TRUE}
BX lr ; Return to caller
ELSE
@@ -360,4 +181,3 @@ _return
ENDIF
END
-
diff --git a/ports_smp/cortex_a5_smp/ac5/src/tx_thread_smp_protection_wait_list_macros.h b/ports_smp/cortex_a5_smp/ac5/src/tx_thread_smp_protection_wait_list_macros.h
deleted file mode 100644
index fec51581..00000000
--- a/ports_smp/cortex_a5_smp/ac5/src/tx_thread_smp_protection_wait_list_macros.h
+++ /dev/null
@@ -1,314 +0,0 @@
-;/***************************************************************************
-; * Copyright (c) 2024 Microsoft Corporation
-; *
-; * 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.
-; *
-; * SPDX-License-Identifier: MIT
-; **************************************************************************/
-;
-;
-;/**************************************************************************/
-;/**************************************************************************/
-;/** */
-;/** ThreadX Component */
-;/** */
-;/** Thread - Low Level SMP Support */
-;/** */
-;/**************************************************************************/
-;/**************************************************************************/
-
- MACRO
-$label _tx_thread_smp_protect_lock_got
-;
-; /* Set the currently owned core. */
-; _tx_thread_smp_protection.tx_thread_smp_protect_core = this_core;
-;
- STR r1, [r2, #8] ; Store this core
-;
-; /* Increment the protection count. */
-; _tx_thread_smp_protection.tx_thread_smp_protect_count++;
-;
- LDR r3, [r2, #12] ; Pickup ownership count
- ADD r3, r3, #1 ; Increment ownership count
- STR r3, [r2, #12] ; Store ownership count
- DMB
-
- IF :DEF:TX_MPCORE_DEBUG_ENABLE
- LSL r3, r1, #2 ; Build offset to array indexes
- LDR r4, =_tx_thread_current_ptr ; Pickup start of the current thread array
- ADD r4, r3, r4 ; Build index into the current thread array
- LDR r3, [r4] ; Pickup current thread for this core
- STR r3, [r2, #4] ; Save current thread pointer
- STR LR, [r2, #16] ; Save caller's return address
- STR r0, [r2, #20] ; Save CPSR
- ENDIF
-
- MEND
-
- MACRO
-$label _tx_thread_smp_protect_remove_from_front_of_list
-;
-; /* Remove ourselves from the list. */
-; _tx_thread_smp_protect_wait_list[_tx_thread_smp_protect_wait_list_head++] = 0xFFFFFFFF;
-;
- MOV r3, #0xFFFFFFFF ; Build the invalid core value
- LDR r4, =_tx_thread_smp_protect_wait_list_head ; Get the address of the head
- LDR r5, [r4] ; Get the value of the head
- LDR r6, =_tx_thread_smp_protect_wait_list ; Get the address of the list
- STR r3, [r6, r5, LSL #2] ; Store the invalid core value
- ADD r5, r5, #1 ; Increment the head
-;
-; /* Did we wrap? */
-; if (_tx_thread_smp_protect_wait_list_head == TX_THREAD_SMP_MAX_CORES + 1)
-; {
-;
- LDR r3, =_tx_thread_smp_protect_wait_list_size ; Load address of core list size
- LDR r3, [r3] ; Load the max cores value
- CMP r5, r3 ; Compare the head to it
- BNE $label._store_new_head ; Are we at the max?
-;
-; _tx_thread_smp_protect_wait_list_head = 0;
-;
- EOR r5, r5, r5 ; We're at the max. Set it to zero
-;
-; }
-;
-$label._store_new_head
-
- STR r5, [r4] ; Store the new head
-;
-; /* We have the lock! */
-; return;
-;
- MEND
-
-
- MACRO
-$label _tx_thread_smp_protect_wait_list_lock_get
-;VOID _tx_thread_smp_protect_wait_list_lock_get()
-;{
-; /* We do this until we have the lock. */
-; while (1)
-; {
-;
-$label._tx_thread_smp_protect_wait_list_lock_get__try_to_get_lock
-;
-; /* Is the list lock available? */
-; _tx_thread_smp_protect_wait_list_lock_protect_in_force = load_exclusive(&_tx_thread_smp_protect_wait_list_lock_protect_in_force);
-;
- LDR r1, =_tx_thread_smp_protect_wait_list_lock_protect_in_force
- LDREX r2, [r1] ; Pickup the protection flag
-;
-; if (protect_in_force == 0)
-; {
-;
- CMP r2, #0
- BNE $label._tx_thread_smp_protect_wait_list_lock_get__try_to_get_lock ; No, protection not available
-;
-; /* Try to get the list. */
-; int status = store_exclusive(&_tx_thread_smp_protect_wait_list_lock_protect_in_force, 1);
-;
- MOV r2, #1 ; Build lock value
- STREX r3, r2, [r1] ; Attempt to get the protection
-;
-; if (status == SUCCESS)
-;
- CMP r3, #0
- BNE $label._tx_thread_smp_protect_wait_list_lock_get__try_to_get_lock ; Did it fail? If so, try again.
-;
-; /* We have the lock! */
-; return;
-;
- MEND
-
-
- MACRO
-$label _tx_thread_smp_protect_wait_list_add
-;VOID _tx_thread_smp_protect_wait_list_add(UINT new_core)
-;{
-;
-; /* We're about to modify the list, so get the list lock. */
-; _tx_thread_smp_protect_wait_list_lock_get();
-;
- PUSH {r1-r2}
-
-$label _tx_thread_smp_protect_wait_list_lock_get
-
- POP {r1-r2}
-;
-; /* Add this core. */
-; _tx_thread_smp_protect_wait_list[_tx_thread_smp_protect_wait_list_tail++] = new_core;
-;
- LDR r3, =_tx_thread_smp_protect_wait_list_tail ; Get the address of the tail
- LDR r4, [r3] ; Get the value of tail
- LDR r5, =_tx_thread_smp_protect_wait_list ; Get the address of the list
- STR r1, [r5, r4, LSL #2] ; Store the new core value
- ADD r4, r4, #1 ; Increment the tail
-;
-; /* Did we wrap? */
-; if (_tx_thread_smp_protect_wait_list_tail == _tx_thread_smp_protect_wait_list_size)
-; {
-;
- LDR r5, =_tx_thread_smp_protect_wait_list_size ; Load max cores address
- LDR r5, [r5] ; Load max cores value
- CMP r4, r5 ; Compare max cores to tail
- BNE $label._tx_thread_smp_protect_wait_list_add__no_wrap ; Did we wrap?
-;
-; _tx_thread_smp_protect_wait_list_tail = 0;
-;
- MOV r4, #0
-;
-; }
-;
-$label._tx_thread_smp_protect_wait_list_add__no_wrap
-
- STR r4, [r3] ; Store the new tail value.
-;
-; /* Release the list lock. */
-; _tx_thread_smp_protect_wait_list_lock_protect_in_force = 0;
-;
- MOV r3, #0 ; Build lock value
- LDR r4, =_tx_thread_smp_protect_wait_list_lock_protect_in_force
- STR r3, [r4] ; Store the new value
-
- MEND
-
-
- MACRO
-$label _tx_thread_smp_protect_wait_list_remove
-;VOID _tx_thread_smp_protect_wait_list_remove(UINT core)
-;{
-;
-; /* Get the core index. */
-; UINT core_index;
-; for (core_index = 0;; core_index++)
-;
- EOR r1, r1, r1 ; Clear for 'core_index'
- LDR r2, =_tx_thread_smp_protect_wait_list ; Get the address of the list
-;
-; {
-;
-$label._tx_thread_smp_protect_wait_list_remove__check_cur_core
-;
-; /* Is this the core? */
-; if (_tx_thread_smp_protect_wait_list[core_index] == core)
-; {
-; break;
-;
- LDR r3, [r2, r1, LSL #2] ; Get the value at the current index
- CMP r3, r0 ; Did we find the core?
- BEQ $label._tx_thread_smp_protect_wait_list_remove__found_core
-;
-; }
-;
- ADD r1, r1, #1 ; Increment cur index
- B $label._tx_thread_smp_protect_wait_list_remove__check_cur_core ; Restart the loop
-;
-; }
-;
-$label._tx_thread_smp_protect_wait_list_remove__found_core
-;
-; /* We're about to modify the list. Get the lock. We need the lock because another
-; core could be simultaneously adding (a core is simultaneously trying to get
-; the inter-core lock) or removing (a core is simultaneously being preempted,
-; like what is currently happening). */
-; _tx_thread_smp_protect_wait_list_lock_get();
-;
- PUSH {r1}
-
-$label _tx_thread_smp_protect_wait_list_lock_get
-
- POP {r1}
-;
-; /* We remove by shifting. */
-; while (core_index != _tx_thread_smp_protect_wait_list_tail)
-; {
-;
-$label._tx_thread_smp_protect_wait_list_remove__compare_index_to_tail
-
- LDR r2, =_tx_thread_smp_protect_wait_list_tail ; Load tail address
- LDR r2, [r2] ; Load tail value
- CMP r1, r2 ; Compare cur index and tail
- BEQ $label._tx_thread_smp_protect_wait_list_remove__removed
-;
-; UINT next_index = core_index + 1;
-;
- MOV r2, r1 ; Move current index to next index register
- ADD r2, r2, #1 ; Add 1
-;
-; if (next_index == _tx_thread_smp_protect_wait_list_size)
-; {
-;
- LDR r3, =_tx_thread_smp_protect_wait_list_size
- LDR r3, [r3]
- CMP r2, r3
- BNE $label._tx_thread_smp_protect_wait_list_remove__next_index_no_wrap
-;
-; next_index = 0;
-;
- MOV r2, #0
-;
-; }
-;
-$label._tx_thread_smp_protect_wait_list_remove__next_index_no_wrap
-;
-; list_cores[core_index] = list_cores[next_index];
-;
- LDR r0, =_tx_thread_smp_protect_wait_list ; Get the address of the list
- LDR r3, [r0, r2, LSL #2] ; Get the value at the next index
- STR r3, [r0, r1, LSL #2] ; Store the value at the current index
-;
-; core_index = next_index;
-;
- MOV r1, r2
-
- B $label._tx_thread_smp_protect_wait_list_remove__compare_index_to_tail
-;
-; }
-;
-$label._tx_thread_smp_protect_wait_list_remove__removed
-;
-; /* Now update the tail. */
-; if (_tx_thread_smp_protect_wait_list_tail == 0)
-; {
-;
- LDR r0, =_tx_thread_smp_protect_wait_list_tail ; Load tail address
- LDR r1, [r0] ; Load tail value
- CMP r1, #0
- BNE $label._tx_thread_smp_protect_wait_list_remove__tail_not_zero
-;
-; _tx_thread_smp_protect_wait_list_tail = _tx_thread_smp_protect_wait_list_size;
-;
- LDR r2, =_tx_thread_smp_protect_wait_list_size
- LDR r1, [r2]
-;
-; }
-;
-$label._tx_thread_smp_protect_wait_list_remove__tail_not_zero
-;
-; _tx_thread_smp_protect_wait_list_tail--;
-;
- SUB r1, r1, #1
- STR r1, [r0] ; Store new tail value
-;
-; /* Release the list lock. */
-; _tx_thread_smp_protect_wait_list_lock_protect_in_force = 0;
-;
- MOV r0, #0 ; Build lock value
- LDR r1, =_tx_thread_smp_protect_wait_list_lock_protect_in_force ; Load lock address
- STR r0, [r1] ; Store the new value
-;
-; /* We're no longer waiting. Note that this should be zero since, again,
-; this function is only called when a thread preemption is occurring. */
-; _tx_thread_smp_protect_wait_counts[core]--;
-;
- MRC p15, 0, r0, c0, c0, 5 ; Read CPU ID register
- AND r0, r0, #0x03 ; Mask off, leaving the CPU ID field
- LDR r1, =_tx_thread_smp_protect_wait_counts ; Load wait list counts
- LDR r2, [r1, r0, LSL #2] ; Load waiting value
- SUB r2, r2, #1 ; Subtract 1
- STR r2, [r1, r0, LSL #2] ; Store new waiting value
- MEND
-
diff --git a/ports_smp/cortex_a5_smp/ac5/src/tx_thread_smp_time_get.s b/ports_smp/cortex_a5_smp/ac5/src/tx_thread_smp_time_get.s
index a378060e..f6e7f066 100644
--- a/ports_smp/cortex_a5_smp/ac5/src/tx_thread_smp_time_get.s
+++ b/ports_smp/cortex_a5_smp/ac5/src/tx_thread_smp_time_get.s
@@ -1,5 +1,6 @@
;/***************************************************************************
; * Copyright (c) 2024 Microsoft Corporation
+; * Copyright (c) 2026-present Eclipse ThreadX contributors
; *
; * This program and the accompanying materials are made available under the
; * terms of the MIT License which is available at
@@ -8,6 +9,7 @@
; * SPDX-License-Identifier: MIT
; **************************************************************************/
;
+; Portions of this file were generated with AI assistance.
;
;/**************************************************************************/
;/**************************************************************************/
@@ -69,7 +71,7 @@
_tx_thread_smp_time_get
MRC p15, 4, r0, c15, c0, 0 ; Read periph base address
- LDR r0, [r0, #0x604] ; Read count register
+ LDR r0, [r0, #0x200] ; Read global timer count low register
IF {INTER} = {TRUE}
BX lr ; Return to caller
@@ -78,4 +80,3 @@ _tx_thread_smp_time_get
ENDIF
END
-
diff --git a/ports_smp/cortex_a5_smp/ac5/src/tx_thread_smp_unprotect.s b/ports_smp/cortex_a5_smp/ac5/src/tx_thread_smp_unprotect.s
index 61645b3e..5dad99a8 100644
--- a/ports_smp/cortex_a5_smp/ac5/src/tx_thread_smp_unprotect.s
+++ b/ports_smp/cortex_a5_smp/ac5/src/tx_thread_smp_unprotect.s
@@ -1,5 +1,6 @@
;/***************************************************************************
; * Copyright (c) 2024 Microsoft Corporation
+; * 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
@@ -7,6 +8,7 @@
; *
; * SPDX-License-Identifier: MIT
; **************************************************************************/
+; Portions of this file were generated with AI assistance.
;
;
;/**************************************************************************/
@@ -33,7 +35,6 @@
IMPORT _tx_thread_current_ptr
IMPORT _tx_thread_smp_protection
IMPORT _tx_thread_preempt_disable
- IMPORT _tx_thread_smp_protect_wait_counts
AREA ||.text||, CODE, READONLY
PRESERVE8
@@ -103,10 +104,6 @@ _tx_thread_smp_unprotect
CMP r3, #0 ; Is the preempt disable flag set?
BNE _still_protected ; Yes, skip the protection release
- LDR r2,=_tx_thread_smp_protect_wait_counts ; Build build address of wait counts
- LDR r3, [r2, r1, LSL #2] ; Pickup wait list value
- CMP r3, #0 ; Are any entities on this core waiting?
- BNE _still_protected ; Yes, skip the protection release
LDR r2,=_tx_thread_smp_protection ; Build address of protection structure
MOV r3, #0xFFFFFFFF ; Build invalid value
diff --git a/ports_smp/cortex_a5_smp/ac5/src/tx_thread_system_return.s b/ports_smp/cortex_a5_smp/ac5/src/tx_thread_system_return.s
index da21d7c1..a2880c1d 100644
--- a/ports_smp/cortex_a5_smp/ac5/src/tx_thread_system_return.s
+++ b/ports_smp/cortex_a5_smp/ac5/src/tx_thread_system_return.s
@@ -1,5 +1,6 @@
;/***************************************************************************
; * Copyright (c) 2024 Microsoft Corporation
+; * Copyright (c) 2026-present Eclipse ThreadX contributors
; *
; * This program and the accompanying materials are made available under the
; * terms of the MIT License which is available at
@@ -8,6 +9,7 @@
; * SPDX-License-Identifier: MIT
; **************************************************************************/
;
+; Portions of this file were generated with AI assistance.
;
;/**************************************************************************/
;/**************************************************************************/
@@ -132,9 +134,10 @@ _tx_skip_solicited_vfp_save
ADD r2, r2, r12 ; Build index into time-slice array
LDR r1, [r2, #0] ; Pickup current time slice
;
-; /* Save current stack and switch to system stack. */
+; /* Save the current stack pointer in the thread's control block. The
+; scheduler runs on this core's banked SVC mode stack, which the startup
+; code set up, so there is no stack switch to perform. */
; _tx_thread_current_ptr[core] -> tx_thread_stack_ptr = sp;
-; sp = _tx_thread_system_stack_ptr[core];
;
STR sp, [r0, #8] ; Save thread stack pointer
;
diff --git a/ports_smp/cortex_a5_smp/ac5/src/tx_thread_vectored_context_save.s b/ports_smp/cortex_a5_smp/ac5/src/tx_thread_vectored_context_save.s
index 69a22693..7e152dfe 100644
--- a/ports_smp/cortex_a5_smp/ac5/src/tx_thread_vectored_context_save.s
+++ b/ports_smp/cortex_a5_smp/ac5/src/tx_thread_vectored_context_save.s
@@ -1,5 +1,6 @@
;/***************************************************************************
; * Copyright (c) 2024 Microsoft Corporation
+; * Copyright (c) 2026-present Eclipse ThreadX contributors
; *
; * This program and the accompanying materials are made available under the
; * terms of the MIT License which is available at
@@ -8,6 +9,7 @@
; * SPDX-License-Identifier: MIT
; **************************************************************************/
;
+; Portions of this file were generated with AI assistance.
;
;/**************************************************************************/
;/**************************************************************************/
@@ -143,11 +145,11 @@ __tx_thread_not_nested_save
;
; /* Note: Minimal context of interrupted thread is already saved. */
;
-; /* Save the current stack pointer in the thread's control block. */
-; _tx_thread_current_ptr[core] -> tx_thread_stack_ptr = sp;
-;
-; /* Switch to the system stack. */
-; sp = _tx_thread_system_stack_ptr[core];
+; /* This routine runs in IRQ mode on this core's banked IRQ stack, which
+; serves as the system stack on this architecture, so there is no stack
+; switch to perform here. The thread's stack pointer is saved in its
+; control block by _tx_thread_context_restore, and only when the
+; interrupt results in preemption. */
;
MOV r10, #0 ; Clear stack limit
diff --git a/ports_smp/cortex_a5_smp/gnu/CMakeLists.txt b/ports_smp/cortex_a5_smp/gnu/CMakeLists.txt
new file mode 100644
index 00000000..28c41af5
--- /dev/null
+++ b/ports_smp/cortex_a5_smp/gnu/CMakeLists.txt
@@ -0,0 +1,38 @@
+# Copyright (c) 2026 Eclipse ThreadX contributors
+# SPDX-License-Identifier: MIT
+# Portions of this file were generated with AI assistance.
+#
+# ThreadX port sources for cortex_a5_smp, GNU tools.
+
+target_sources(${PROJECT_NAME}
+ PRIVATE
+ # {{BEGIN_TARGET_SOURCES}}
+ ${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_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_irq_nesting_end.S
+ ${CMAKE_CURRENT_LIST_DIR}/src/tx_thread_irq_nesting_start.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_thread_vectored_context_save.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_smp/cortex_a5_smp/gnu/example_build/build_threadx.sh b/ports_smp/cortex_a5_smp/gnu/example_build/build_threadx.sh
new file mode 100755
index 00000000..88c68def
--- /dev/null
+++ b/ports_smp/cortex_a5_smp/gnu/example_build/build_threadx.sh
@@ -0,0 +1,295 @@
+#!/bin/sh
+##############################################################################
+# 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.
+#
+# SPDX-License-Identifier: MIT
+##############################################################################
+
+set -e
+cd "$(dirname "$0")"
+
+# this script builds the ThreadX library for the Cortex-A5 SMP port using
+# GNU toolchain or llvm/clang toolchain (defaults to GNU).
+: "${TOOLCHAIN:=gnu}"
+
+case "${TOOLCHAIN}" in
+ gnu)
+ CC="arm-none-eabi-gcc"
+ AR="arm-none-eabi-ar"
+ TARGET_FLAGS=""
+ ;;
+ atfe)
+ CC="${ATFE_CLANG:-clang}"
+ case "${CC}" in
+ */*) AR="$(dirname "${CC}")/llvm-ar" ;;
+ *) AR="llvm-ar" ;;
+ esac
+ TARGET_FLAGS="--target=arm-none-eabi"
+ ;;
+ *)
+ echo "Unknown TOOLCHAIN: ${TOOLCHAIN}" >&2
+ exit 1
+ ;;
+esac
+
+rm -f tx.a
+"${CC}" ${TARGET_FLAGS} -c -g -mcpu=cortex-a5 tx_initialize_low_level.S
+"${CC}" ${TARGET_FLAGS} -c -g -mcpu=cortex-a5 ../src/tx_thread_context_restore.S
+"${CC}" ${TARGET_FLAGS} -c -g -mcpu=cortex-a5 ../src/tx_thread_context_save.S
+"${CC}" ${TARGET_FLAGS} -c -g -mcpu=cortex-a5 ../src/tx_thread_interrupt_control.S
+"${CC}" ${TARGET_FLAGS} -c -g -mcpu=cortex-a5 ../src/tx_thread_interrupt_disable.S
+"${CC}" ${TARGET_FLAGS} -c -g -mcpu=cortex-a5 ../src/tx_thread_interrupt_restore.S
+"${CC}" ${TARGET_FLAGS} -c -g -mcpu=cortex-a5 ../src/tx_thread_irq_nesting_end.S
+"${CC}" ${TARGET_FLAGS} -c -g -mcpu=cortex-a5 ../src/tx_thread_irq_nesting_start.S
+"${CC}" ${TARGET_FLAGS} -c -g -mcpu=cortex-a5 ../src/tx_thread_schedule.S
+"${CC}" ${TARGET_FLAGS} -c -g -mcpu=cortex-a5 ../src/tx_thread_smp_core_get.S
+"${CC}" ${TARGET_FLAGS} -c -g -mcpu=cortex-a5 ../src/tx_thread_smp_core_preempt.S
+"${CC}" ${TARGET_FLAGS} -c -g -mcpu=cortex-a5 ../src/tx_thread_smp_current_state_get.S
+"${CC}" ${TARGET_FLAGS} -c -g -mcpu=cortex-a5 ../src/tx_thread_smp_current_thread_get.S
+"${CC}" ${TARGET_FLAGS} -c -g -mcpu=cortex-a5 ../src/tx_thread_smp_initialize_wait.S
+"${CC}" ${TARGET_FLAGS} -c -g -mcpu=cortex-a5 ../src/tx_thread_smp_low_level_initialize.S
+"${CC}" ${TARGET_FLAGS} -c -g -mcpu=cortex-a5 ../src/tx_thread_smp_protect.S
+"${CC}" ${TARGET_FLAGS} -c -g -mcpu=cortex-a5 ../src/tx_thread_smp_time_get.S
+"${CC}" ${TARGET_FLAGS} -c -g -mcpu=cortex-a5 ../src/tx_thread_smp_unprotect.S
+"${CC}" ${TARGET_FLAGS} -c -g -mcpu=cortex-a5 ../src/tx_thread_stack_build.S
+"${CC}" ${TARGET_FLAGS} -c -g -mcpu=cortex-a5 ../src/tx_thread_system_return.S
+"${CC}" ${TARGET_FLAGS} -c -g -mcpu=cortex-a5 ../src/tx_thread_vectored_context_save.S
+"${CC}" ${TARGET_FLAGS} -c -g -mcpu=cortex-a5 ../src/tx_timer_interrupt.S
+"${CC}" ${TARGET_FLAGS} -c -g -mcpu=cortex-a5 -I../../../../common_smp/inc -I../inc ../../../../common_smp/src/tx_block_allocate.c
+"${CC}" ${TARGET_FLAGS} -c -g -mcpu=cortex-a5 -I../../../../common_smp/inc -I../inc ../../../../common_smp/src/tx_block_pool_cleanup.c
+"${CC}" ${TARGET_FLAGS} -c -g -mcpu=cortex-a5 -I../../../../common_smp/inc -I../inc ../../../../common_smp/src/tx_block_pool_create.c
+"${CC}" ${TARGET_FLAGS} -c -g -mcpu=cortex-a5 -I../../../../common_smp/inc -I../inc ../../../../common_smp/src/tx_block_pool_delete.c
+"${CC}" ${TARGET_FLAGS} -c -g -mcpu=cortex-a5 -I../../../../common_smp/inc -I../inc ../../../../common_smp/src/tx_block_pool_info_get.c
+"${CC}" ${TARGET_FLAGS} -c -g -mcpu=cortex-a5 -I../../../../common_smp/inc -I../inc ../../../../common_smp/src/tx_block_pool_initialize.c
+"${CC}" ${TARGET_FLAGS} -c -g -mcpu=cortex-a5 -I../../../../common_smp/inc -I../inc ../../../../common_smp/src/tx_block_pool_performance_info_get.c
+"${CC}" ${TARGET_FLAGS} -c -g -mcpu=cortex-a5 -I../../../../common_smp/inc -I../inc ../../../../common_smp/src/tx_block_pool_performance_system_info_get.c
+"${CC}" ${TARGET_FLAGS} -c -g -mcpu=cortex-a5 -I../../../../common_smp/inc -I../inc ../../../../common_smp/src/tx_block_pool_prioritize.c
+"${CC}" ${TARGET_FLAGS} -c -g -mcpu=cortex-a5 -I../../../../common_smp/inc -I../inc ../../../../common_smp/src/tx_block_release.c
+"${CC}" ${TARGET_FLAGS} -c -g -mcpu=cortex-a5 -I../../../../common_smp/inc -I../inc ../../../../common_smp/src/tx_byte_allocate.c
+"${CC}" ${TARGET_FLAGS} -c -g -mcpu=cortex-a5 -I../../../../common_smp/inc -I../inc ../../../../common_smp/src/tx_byte_pool_cleanup.c
+"${CC}" ${TARGET_FLAGS} -c -g -mcpu=cortex-a5 -I../../../../common_smp/inc -I../inc ../../../../common_smp/src/tx_byte_pool_create.c
+"${CC}" ${TARGET_FLAGS} -c -g -mcpu=cortex-a5 -I../../../../common_smp/inc -I../inc ../../../../common_smp/src/tx_byte_pool_delete.c
+"${CC}" ${TARGET_FLAGS} -c -g -mcpu=cortex-a5 -I../../../../common_smp/inc -I../inc ../../../../common_smp/src/tx_byte_pool_info_get.c
+"${CC}" ${TARGET_FLAGS} -c -g -mcpu=cortex-a5 -I../../../../common_smp/inc -I../inc ../../../../common_smp/src/tx_byte_pool_initialize.c
+"${CC}" ${TARGET_FLAGS} -c -g -mcpu=cortex-a5 -I../../../../common_smp/inc -I../inc ../../../../common_smp/src/tx_byte_pool_performance_info_get.c
+"${CC}" ${TARGET_FLAGS} -c -g -mcpu=cortex-a5 -I../../../../common_smp/inc -I../inc ../../../../common_smp/src/tx_byte_pool_performance_system_info_get.c
+"${CC}" ${TARGET_FLAGS} -c -g -mcpu=cortex-a5 -I../../../../common_smp/inc -I../inc ../../../../common_smp/src/tx_byte_pool_prioritize.c
+"${CC}" ${TARGET_FLAGS} -c -g -mcpu=cortex-a5 -I../../../../common_smp/inc -I../inc ../../../../common_smp/src/tx_byte_pool_search.c
+"${CC}" ${TARGET_FLAGS} -c -g -mcpu=cortex-a5 -I../../../../common_smp/inc -I../inc ../../../../common_smp/src/tx_byte_release.c
+"${CC}" ${TARGET_FLAGS} -c -g -mcpu=cortex-a5 -I../../../../common_smp/inc -I../inc ../../../../common_smp/src/tx_event_flags_cleanup.c
+"${CC}" ${TARGET_FLAGS} -c -g -mcpu=cortex-a5 -I../../../../common_smp/inc -I../inc ../../../../common_smp/src/tx_event_flags_create.c
+"${CC}" ${TARGET_FLAGS} -c -g -mcpu=cortex-a5 -I../../../../common_smp/inc -I../inc ../../../../common_smp/src/tx_event_flags_delete.c
+"${CC}" ${TARGET_FLAGS} -c -g -mcpu=cortex-a5 -I../../../../common_smp/inc -I../inc ../../../../common_smp/src/tx_event_flags_get.c
+"${CC}" ${TARGET_FLAGS} -c -g -mcpu=cortex-a5 -I../../../../common_smp/inc -I../inc ../../../../common_smp/src/tx_event_flags_info_get.c
+"${CC}" ${TARGET_FLAGS} -c -g -mcpu=cortex-a5 -I../../../../common_smp/inc -I../inc ../../../../common_smp/src/tx_event_flags_initialize.c
+"${CC}" ${TARGET_FLAGS} -c -g -mcpu=cortex-a5 -I../../../../common_smp/inc -I../inc ../../../../common_smp/src/tx_event_flags_performance_info_get.c
+"${CC}" ${TARGET_FLAGS} -c -g -mcpu=cortex-a5 -I../../../../common_smp/inc -I../inc ../../../../common_smp/src/tx_event_flags_performance_system_info_get.c
+"${CC}" ${TARGET_FLAGS} -c -g -mcpu=cortex-a5 -I../../../../common_smp/inc -I../inc ../../../../common_smp/src/tx_event_flags_set.c
+"${CC}" ${TARGET_FLAGS} -c -g -mcpu=cortex-a5 -I../../../../common_smp/inc -I../inc ../../../../common_smp/src/tx_event_flags_set_notify.c
+"${CC}" ${TARGET_FLAGS} -c -g -mcpu=cortex-a5 -I../../../../common_smp/inc -I../inc ../../../../common_smp/src/tx_initialize_high_level.c
+"${CC}" ${TARGET_FLAGS} -c -g -mcpu=cortex-a5 -I../../../../common_smp/inc -I../inc ../../../../common_smp/src/tx_initialize_kernel_enter.c
+"${CC}" ${TARGET_FLAGS} -c -g -mcpu=cortex-a5 -I../../../../common_smp/inc -I../inc ../../../../common_smp/src/tx_initialize_kernel_setup.c
+"${CC}" ${TARGET_FLAGS} -c -g -mcpu=cortex-a5 -I../../../../common_smp/inc -I../inc ../../../../common_smp/src/tx_mutex_cleanup.c
+"${CC}" ${TARGET_FLAGS} -c -g -mcpu=cortex-a5 -I../../../../common_smp/inc -I../inc ../../../../common_smp/src/tx_mutex_create.c
+"${CC}" ${TARGET_FLAGS} -c -g -mcpu=cortex-a5 -I../../../../common_smp/inc -I../inc ../../../../common_smp/src/tx_mutex_delete.c
+"${CC}" ${TARGET_FLAGS} -c -g -mcpu=cortex-a5 -I../../../../common_smp/inc -I../inc ../../../../common_smp/src/tx_mutex_get.c
+"${CC}" ${TARGET_FLAGS} -c -g -mcpu=cortex-a5 -I../../../../common_smp/inc -I../inc ../../../../common_smp/src/tx_mutex_info_get.c
+"${CC}" ${TARGET_FLAGS} -c -g -mcpu=cortex-a5 -I../../../../common_smp/inc -I../inc ../../../../common_smp/src/tx_mutex_initialize.c
+"${CC}" ${TARGET_FLAGS} -c -g -mcpu=cortex-a5 -I../../../../common_smp/inc -I../inc ../../../../common_smp/src/tx_mutex_performance_info_get.c
+"${CC}" ${TARGET_FLAGS} -c -g -mcpu=cortex-a5 -I../../../../common_smp/inc -I../inc ../../../../common_smp/src/tx_mutex_performance_system_info_get.c
+"${CC}" ${TARGET_FLAGS} -c -g -mcpu=cortex-a5 -I../../../../common_smp/inc -I../inc ../../../../common_smp/src/tx_mutex_prioritize.c
+"${CC}" ${TARGET_FLAGS} -c -g -mcpu=cortex-a5 -I../../../../common_smp/inc -I../inc ../../../../common_smp/src/tx_mutex_priority_change.c
+"${CC}" ${TARGET_FLAGS} -c -g -mcpu=cortex-a5 -I../../../../common_smp/inc -I../inc ../../../../common_smp/src/tx_mutex_put.c
+"${CC}" ${TARGET_FLAGS} -c -g -mcpu=cortex-a5 -I../../../../common_smp/inc -I../inc ../../../../common_smp/src/tx_queue_cleanup.c
+"${CC}" ${TARGET_FLAGS} -c -g -mcpu=cortex-a5 -I../../../../common_smp/inc -I../inc ../../../../common_smp/src/tx_queue_create.c
+"${CC}" ${TARGET_FLAGS} -c -g -mcpu=cortex-a5 -I../../../../common_smp/inc -I../inc ../../../../common_smp/src/tx_queue_delete.c
+"${CC}" ${TARGET_FLAGS} -c -g -mcpu=cortex-a5 -I../../../../common_smp/inc -I../inc ../../../../common_smp/src/tx_queue_flush.c
+"${CC}" ${TARGET_FLAGS} -c -g -mcpu=cortex-a5 -I../../../../common_smp/inc -I../inc ../../../../common_smp/src/tx_queue_front_send.c
+"${CC}" ${TARGET_FLAGS} -c -g -mcpu=cortex-a5 -I../../../../common_smp/inc -I../inc ../../../../common_smp/src/tx_queue_info_get.c
+"${CC}" ${TARGET_FLAGS} -c -g -mcpu=cortex-a5 -I../../../../common_smp/inc -I../inc ../../../../common_smp/src/tx_queue_initialize.c
+"${CC}" ${TARGET_FLAGS} -c -g -mcpu=cortex-a5 -I../../../../common_smp/inc -I../inc ../../../../common_smp/src/tx_queue_performance_info_get.c
+"${CC}" ${TARGET_FLAGS} -c -g -mcpu=cortex-a5 -I../../../../common_smp/inc -I../inc ../../../../common_smp/src/tx_queue_performance_system_info_get.c
+"${CC}" ${TARGET_FLAGS} -c -g -mcpu=cortex-a5 -I../../../../common_smp/inc -I../inc ../../../../common_smp/src/tx_queue_prioritize.c
+"${CC}" ${TARGET_FLAGS} -c -g -mcpu=cortex-a5 -I../../../../common_smp/inc -I../inc ../../../../common_smp/src/tx_queue_receive.c
+"${CC}" ${TARGET_FLAGS} -c -g -mcpu=cortex-a5 -I../../../../common_smp/inc -I../inc ../../../../common_smp/src/tx_queue_send.c
+"${CC}" ${TARGET_FLAGS} -c -g -mcpu=cortex-a5 -I../../../../common_smp/inc -I../inc ../../../../common_smp/src/tx_queue_send_notify.c
+"${CC}" ${TARGET_FLAGS} -c -g -mcpu=cortex-a5 -I../../../../common_smp/inc -I../inc ../../../../common_smp/src/tx_semaphore_ceiling_put.c
+"${CC}" ${TARGET_FLAGS} -c -g -mcpu=cortex-a5 -I../../../../common_smp/inc -I../inc ../../../../common_smp/src/tx_semaphore_cleanup.c
+"${CC}" ${TARGET_FLAGS} -c -g -mcpu=cortex-a5 -I../../../../common_smp/inc -I../inc ../../../../common_smp/src/tx_semaphore_create.c
+"${CC}" ${TARGET_FLAGS} -c -g -mcpu=cortex-a5 -I../../../../common_smp/inc -I../inc ../../../../common_smp/src/tx_semaphore_delete.c
+"${CC}" ${TARGET_FLAGS} -c -g -mcpu=cortex-a5 -I../../../../common_smp/inc -I../inc ../../../../common_smp/src/tx_semaphore_get.c
+"${CC}" ${TARGET_FLAGS} -c -g -mcpu=cortex-a5 -I../../../../common_smp/inc -I../inc ../../../../common_smp/src/tx_semaphore_info_get.c
+"${CC}" ${TARGET_FLAGS} -c -g -mcpu=cortex-a5 -I../../../../common_smp/inc -I../inc ../../../../common_smp/src/tx_semaphore_initialize.c
+"${CC}" ${TARGET_FLAGS} -c -g -mcpu=cortex-a5 -I../../../../common_smp/inc -I../inc ../../../../common_smp/src/tx_semaphore_performance_info_get.c
+"${CC}" ${TARGET_FLAGS} -c -g -mcpu=cortex-a5 -I../../../../common_smp/inc -I../inc ../../../../common_smp/src/tx_semaphore_performance_system_info_get.c
+"${CC}" ${TARGET_FLAGS} -c -g -mcpu=cortex-a5 -I../../../../common_smp/inc -I../inc ../../../../common_smp/src/tx_semaphore_prioritize.c
+"${CC}" ${TARGET_FLAGS} -c -g -mcpu=cortex-a5 -I../../../../common_smp/inc -I../inc ../../../../common_smp/src/tx_semaphore_put.c
+"${CC}" ${TARGET_FLAGS} -c -g -mcpu=cortex-a5 -I../../../../common_smp/inc -I../inc ../../../../common_smp/src/tx_semaphore_put_notify.c
+"${CC}" ${TARGET_FLAGS} -c -g -mcpu=cortex-a5 -I../../../../common_smp/inc -I../inc ../../../../common_smp/src/tx_thread_create.c
+"${CC}" ${TARGET_FLAGS} -c -g -mcpu=cortex-a5 -I../../../../common_smp/inc -I../inc ../../../../common_smp/src/tx_thread_delete.c
+"${CC}" ${TARGET_FLAGS} -c -g -mcpu=cortex-a5 -I../../../../common_smp/inc -I../inc ../../../../common_smp/src/tx_thread_entry_exit_notify.c
+"${CC}" ${TARGET_FLAGS} -c -g -mcpu=cortex-a5 -I../../../../common_smp/inc -I../inc ../../../../common_smp/src/tx_thread_identify.c
+"${CC}" ${TARGET_FLAGS} -c -g -mcpu=cortex-a5 -I../../../../common_smp/inc -I../inc ../../../../common_smp/src/tx_thread_info_get.c
+"${CC}" ${TARGET_FLAGS} -c -g -mcpu=cortex-a5 -I../../../../common_smp/inc -I../inc ../../../../common_smp/src/tx_thread_initialize.c
+"${CC}" ${TARGET_FLAGS} -c -g -mcpu=cortex-a5 -I../../../../common_smp/inc -I../inc ../../../../common_smp/src/tx_thread_performance_info_get.c
+"${CC}" ${TARGET_FLAGS} -c -g -mcpu=cortex-a5 -I../../../../common_smp/inc -I../inc ../../../../common_smp/src/tx_thread_performance_system_info_get.c
+"${CC}" ${TARGET_FLAGS} -c -g -mcpu=cortex-a5 -I../../../../common_smp/inc -I../inc ../../../../common_smp/src/tx_thread_preemption_change.c
+"${CC}" ${TARGET_FLAGS} -c -g -mcpu=cortex-a5 -I../../../../common_smp/inc -I../inc ../../../../common_smp/src/tx_thread_priority_change.c
+"${CC}" ${TARGET_FLAGS} -c -g -mcpu=cortex-a5 -I../../../../common_smp/inc -I../inc ../../../../common_smp/src/tx_thread_relinquish.c
+"${CC}" ${TARGET_FLAGS} -c -g -mcpu=cortex-a5 -I../../../../common_smp/inc -I../inc ../../../../common_smp/src/tx_thread_reset.c
+"${CC}" ${TARGET_FLAGS} -c -g -mcpu=cortex-a5 -I../../../../common_smp/inc -I../inc ../../../../common_smp/src/tx_thread_resume.c
+"${CC}" ${TARGET_FLAGS} -c -g -mcpu=cortex-a5 -I../../../../common_smp/inc -I../inc ../../../../common_smp/src/tx_thread_shell_entry.c
+"${CC}" ${TARGET_FLAGS} -c -g -mcpu=cortex-a5 -I../../../../common_smp/inc -I../inc ../../../../common_smp/src/tx_thread_sleep.c
+"${CC}" ${TARGET_FLAGS} -c -g -mcpu=cortex-a5 -I../../../../common_smp/inc -I../inc ../../../../common_smp/src/tx_thread_stack_analyze.c
+"${CC}" ${TARGET_FLAGS} -c -g -mcpu=cortex-a5 -I../../../../common_smp/inc -I../inc ../../../../common_smp/src/tx_thread_stack_error_handler.c
+"${CC}" ${TARGET_FLAGS} -c -g -mcpu=cortex-a5 -I../../../../common_smp/inc -I../inc ../../../../common_smp/src/tx_thread_stack_error_notify.c
+"${CC}" ${TARGET_FLAGS} -c -g -mcpu=cortex-a5 -I../../../../common_smp/inc -I../inc ../../../../common_smp/src/tx_thread_suspend.c
+"${CC}" ${TARGET_FLAGS} -c -g -mcpu=cortex-a5 -I../../../../common_smp/inc -I../inc ../../../../common_smp/src/tx_thread_system_preempt_check.c
+"${CC}" ${TARGET_FLAGS} -c -g -mcpu=cortex-a5 -I../../../../common_smp/inc -I../inc ../../../../common_smp/src/tx_thread_system_resume.c
+"${CC}" ${TARGET_FLAGS} -c -g -mcpu=cortex-a5 -I../../../../common_smp/inc -I../inc ../../../../common_smp/src/tx_thread_system_suspend.c
+"${CC}" ${TARGET_FLAGS} -c -g -mcpu=cortex-a5 -I../../../../common_smp/inc -I../inc ../../../../common_smp/src/tx_thread_terminate.c
+"${CC}" ${TARGET_FLAGS} -c -g -mcpu=cortex-a5 -I../../../../common_smp/inc -I../inc ../../../../common_smp/src/tx_thread_time_slice.c
+"${CC}" ${TARGET_FLAGS} -c -g -mcpu=cortex-a5 -I../../../../common_smp/inc -I../inc ../../../../common_smp/src/tx_thread_time_slice_change.c
+"${CC}" ${TARGET_FLAGS} -c -g -mcpu=cortex-a5 -I../../../../common_smp/inc -I../inc ../../../../common_smp/src/tx_thread_timeout.c
+"${CC}" ${TARGET_FLAGS} -c -g -mcpu=cortex-a5 -I../../../../common_smp/inc -I../inc ../../../../common_smp/src/tx_thread_wait_abort.c
+"${CC}" ${TARGET_FLAGS} -c -g -mcpu=cortex-a5 -I../../../../common_smp/inc -I../inc ../../../../common_smp/src/tx_time_get.c
+"${CC}" ${TARGET_FLAGS} -c -g -mcpu=cortex-a5 -I../../../../common_smp/inc -I../inc ../../../../common_smp/src/tx_time_set.c
+"${CC}" ${TARGET_FLAGS} -c -g -mcpu=cortex-a5 -I../../../../common_smp/inc -I../inc ../../../../common_smp/src/tx_timer_activate.c
+"${CC}" ${TARGET_FLAGS} -c -g -mcpu=cortex-a5 -I../../../../common_smp/inc -I../inc ../../../../common_smp/src/tx_timer_change.c
+"${CC}" ${TARGET_FLAGS} -c -g -mcpu=cortex-a5 -I../../../../common_smp/inc -I../inc ../../../../common_smp/src/tx_timer_create.c
+"${CC}" ${TARGET_FLAGS} -c -g -mcpu=cortex-a5 -I../../../../common_smp/inc -I../inc ../../../../common_smp/src/tx_timer_deactivate.c
+"${CC}" ${TARGET_FLAGS} -c -g -mcpu=cortex-a5 -I../../../../common_smp/inc -I../inc ../../../../common_smp/src/tx_timer_delete.c
+"${CC}" ${TARGET_FLAGS} -c -g -mcpu=cortex-a5 -I../../../../common_smp/inc -I../inc ../../../../common_smp/src/tx_timer_expiration_process.c
+"${CC}" ${TARGET_FLAGS} -c -g -mcpu=cortex-a5 -I../../../../common_smp/inc -I../inc ../../../../common_smp/src/tx_timer_info_get.c
+"${CC}" ${TARGET_FLAGS} -c -g -mcpu=cortex-a5 -I../../../../common_smp/inc -I../inc ../../../../common_smp/src/tx_timer_initialize.c
+"${CC}" ${TARGET_FLAGS} -c -g -mcpu=cortex-a5 -I../../../../common_smp/inc -I../inc ../../../../common_smp/src/tx_timer_performance_info_get.c
+"${CC}" ${TARGET_FLAGS} -c -g -mcpu=cortex-a5 -I../../../../common_smp/inc -I../inc ../../../../common_smp/src/tx_timer_performance_system_info_get.c
+"${CC}" ${TARGET_FLAGS} -c -g -mcpu=cortex-a5 -I../../../../common_smp/inc -I../inc ../../../../common_smp/src/tx_timer_system_activate.c
+"${CC}" ${TARGET_FLAGS} -c -g -mcpu=cortex-a5 -I../../../../common_smp/inc -I../inc ../../../../common_smp/src/tx_timer_system_deactivate.c
+"${CC}" ${TARGET_FLAGS} -c -g -mcpu=cortex-a5 -I../../../../common_smp/inc -I../inc ../../../../common_smp/src/tx_timer_thread_entry.c
+"${CC}" ${TARGET_FLAGS} -c -g -mcpu=cortex-a5 -I../../../../common_smp/inc -I../inc ../../../../common_smp/src/tx_trace_enable.c
+"${CC}" ${TARGET_FLAGS} -c -g -mcpu=cortex-a5 -I../../../../common_smp/inc -I../inc ../../../../common_smp/src/tx_trace_disable.c
+"${CC}" ${TARGET_FLAGS} -c -g -mcpu=cortex-a5 -I../../../../common_smp/inc -I../inc ../../../../common_smp/src/tx_trace_initialize.c
+"${CC}" ${TARGET_FLAGS} -c -g -mcpu=cortex-a5 -I../../../../common_smp/inc -I../inc ../../../../common_smp/src/tx_trace_interrupt_control.c
+"${CC}" ${TARGET_FLAGS} -c -g -mcpu=cortex-a5 -I../../../../common_smp/inc -I../inc ../../../../common_smp/src/tx_trace_isr_enter_insert.c
+"${CC}" ${TARGET_FLAGS} -c -g -mcpu=cortex-a5 -I../../../../common_smp/inc -I../inc ../../../../common_smp/src/tx_trace_isr_exit_insert.c
+"${CC}" ${TARGET_FLAGS} -c -g -mcpu=cortex-a5 -I../../../../common_smp/inc -I../inc ../../../../common_smp/src/tx_trace_object_register.c
+"${CC}" ${TARGET_FLAGS} -c -g -mcpu=cortex-a5 -I../../../../common_smp/inc -I../inc ../../../../common_smp/src/tx_trace_object_unregister.c
+"${CC}" ${TARGET_FLAGS} -c -g -mcpu=cortex-a5 -I../../../../common_smp/inc -I../inc ../../../../common_smp/src/tx_trace_user_event_insert.c
+"${CC}" ${TARGET_FLAGS} -c -g -mcpu=cortex-a5 -I../../../../common_smp/inc -I../inc ../../../../common_smp/src/tx_trace_buffer_full_notify.c
+"${CC}" ${TARGET_FLAGS} -c -g -mcpu=cortex-a5 -I../../../../common_smp/inc -I../inc ../../../../common_smp/src/tx_trace_event_filter.c
+"${CC}" ${TARGET_FLAGS} -c -g -mcpu=cortex-a5 -I../../../../common_smp/inc -I../inc ../../../../common_smp/src/tx_trace_event_unfilter.c
+"${CC}" ${TARGET_FLAGS} -c -g -mcpu=cortex-a5 -I../../../../common_smp/inc -I../inc ../../../../common_smp/src/txe_block_allocate.c
+"${CC}" ${TARGET_FLAGS} -c -g -mcpu=cortex-a5 -I../../../../common_smp/inc -I../inc ../../../../common_smp/src/txe_block_pool_create.c
+"${CC}" ${TARGET_FLAGS} -c -g -mcpu=cortex-a5 -I../../../../common_smp/inc -I../inc ../../../../common_smp/src/txe_block_pool_delete.c
+"${CC}" ${TARGET_FLAGS} -c -g -mcpu=cortex-a5 -I../../../../common_smp/inc -I../inc ../../../../common_smp/src/txe_block_pool_info_get.c
+"${CC}" ${TARGET_FLAGS} -c -g -mcpu=cortex-a5 -I../../../../common_smp/inc -I../inc ../../../../common_smp/src/txe_block_pool_prioritize.c
+"${CC}" ${TARGET_FLAGS} -c -g -mcpu=cortex-a5 -I../../../../common_smp/inc -I../inc ../../../../common_smp/src/txe_block_release.c
+"${CC}" ${TARGET_FLAGS} -c -g -mcpu=cortex-a5 -I../../../../common_smp/inc -I../inc ../../../../common_smp/src/txe_byte_allocate.c
+"${CC}" ${TARGET_FLAGS} -c -g -mcpu=cortex-a5 -I../../../../common_smp/inc -I../inc ../../../../common_smp/src/txe_byte_pool_create.c
+"${CC}" ${TARGET_FLAGS} -c -g -mcpu=cortex-a5 -I../../../../common_smp/inc -I../inc ../../../../common_smp/src/txe_byte_pool_delete.c
+"${CC}" ${TARGET_FLAGS} -c -g -mcpu=cortex-a5 -I../../../../common_smp/inc -I../inc ../../../../common_smp/src/txe_byte_pool_info_get.c
+"${CC}" ${TARGET_FLAGS} -c -g -mcpu=cortex-a5 -I../../../../common_smp/inc -I../inc ../../../../common_smp/src/txe_byte_pool_prioritize.c
+"${CC}" ${TARGET_FLAGS} -c -g -mcpu=cortex-a5 -I../../../../common_smp/inc -I../inc ../../../../common_smp/src/txe_byte_release.c
+"${CC}" ${TARGET_FLAGS} -c -g -mcpu=cortex-a5 -I../../../../common_smp/inc -I../inc ../../../../common_smp/src/txe_event_flags_create.c
+"${CC}" ${TARGET_FLAGS} -c -g -mcpu=cortex-a5 -I../../../../common_smp/inc -I../inc ../../../../common_smp/src/txe_event_flags_delete.c
+"${CC}" ${TARGET_FLAGS} -c -g -mcpu=cortex-a5 -I../../../../common_smp/inc -I../inc ../../../../common_smp/src/txe_event_flags_get.c
+"${CC}" ${TARGET_FLAGS} -c -g -mcpu=cortex-a5 -I../../../../common_smp/inc -I../inc ../../../../common_smp/src/txe_event_flags_info_get.c
+"${CC}" ${TARGET_FLAGS} -c -g -mcpu=cortex-a5 -I../../../../common_smp/inc -I../inc ../../../../common_smp/src/txe_event_flags_set.c
+"${CC}" ${TARGET_FLAGS} -c -g -mcpu=cortex-a5 -I../../../../common_smp/inc -I../inc ../../../../common_smp/src/txe_event_flags_set_notify.c
+"${CC}" ${TARGET_FLAGS} -c -g -mcpu=cortex-a5 -I../../../../common_smp/inc -I../inc ../../../../common_smp/src/txe_mutex_create.c
+"${CC}" ${TARGET_FLAGS} -c -g -mcpu=cortex-a5 -I../../../../common_smp/inc -I../inc ../../../../common_smp/src/txe_mutex_delete.c
+"${CC}" ${TARGET_FLAGS} -c -g -mcpu=cortex-a5 -I../../../../common_smp/inc -I../inc ../../../../common_smp/src/txe_mutex_get.c
+"${CC}" ${TARGET_FLAGS} -c -g -mcpu=cortex-a5 -I../../../../common_smp/inc -I../inc ../../../../common_smp/src/txe_mutex_info_get.c
+"${CC}" ${TARGET_FLAGS} -c -g -mcpu=cortex-a5 -I../../../../common_smp/inc -I../inc ../../../../common_smp/src/txe_mutex_prioritize.c
+"${CC}" ${TARGET_FLAGS} -c -g -mcpu=cortex-a5 -I../../../../common_smp/inc -I../inc ../../../../common_smp/src/txe_mutex_put.c
+"${CC}" ${TARGET_FLAGS} -c -g -mcpu=cortex-a5 -I../../../../common_smp/inc -I../inc ../../../../common_smp/src/txe_queue_create.c
+"${CC}" ${TARGET_FLAGS} -c -g -mcpu=cortex-a5 -I../../../../common_smp/inc -I../inc ../../../../common_smp/src/txe_queue_delete.c
+"${CC}" ${TARGET_FLAGS} -c -g -mcpu=cortex-a5 -I../../../../common_smp/inc -I../inc ../../../../common_smp/src/txe_queue_flush.c
+"${CC}" ${TARGET_FLAGS} -c -g -mcpu=cortex-a5 -I../../../../common_smp/inc -I../inc ../../../../common_smp/src/txe_queue_front_send.c
+"${CC}" ${TARGET_FLAGS} -c -g -mcpu=cortex-a5 -I../../../../common_smp/inc -I../inc ../../../../common_smp/src/txe_queue_info_get.c
+"${CC}" ${TARGET_FLAGS} -c -g -mcpu=cortex-a5 -I../../../../common_smp/inc -I../inc ../../../../common_smp/src/txe_queue_prioritize.c
+"${CC}" ${TARGET_FLAGS} -c -g -mcpu=cortex-a5 -I../../../../common_smp/inc -I../inc ../../../../common_smp/src/txe_queue_receive.c
+"${CC}" ${TARGET_FLAGS} -c -g -mcpu=cortex-a5 -I../../../../common_smp/inc -I../inc ../../../../common_smp/src/txe_queue_send.c
+"${CC}" ${TARGET_FLAGS} -c -g -mcpu=cortex-a5 -I../../../../common_smp/inc -I../inc ../../../../common_smp/src/txe_queue_send_notify.c
+"${CC}" ${TARGET_FLAGS} -c -g -mcpu=cortex-a5 -I../../../../common_smp/inc -I../inc ../../../../common_smp/src/txe_semaphore_ceiling_put.c
+"${CC}" ${TARGET_FLAGS} -c -g -mcpu=cortex-a5 -I../../../../common_smp/inc -I../inc ../../../../common_smp/src/txe_semaphore_create.c
+"${CC}" ${TARGET_FLAGS} -c -g -mcpu=cortex-a5 -I../../../../common_smp/inc -I../inc ../../../../common_smp/src/txe_semaphore_delete.c
+"${CC}" ${TARGET_FLAGS} -c -g -mcpu=cortex-a5 -I../../../../common_smp/inc -I../inc ../../../../common_smp/src/txe_semaphore_get.c
+"${CC}" ${TARGET_FLAGS} -c -g -mcpu=cortex-a5 -I../../../../common_smp/inc -I../inc ../../../../common_smp/src/txe_semaphore_info_get.c
+"${CC}" ${TARGET_FLAGS} -c -g -mcpu=cortex-a5 -I../../../../common_smp/inc -I../inc ../../../../common_smp/src/txe_semaphore_prioritize.c
+"${CC}" ${TARGET_FLAGS} -c -g -mcpu=cortex-a5 -I../../../../common_smp/inc -I../inc ../../../../common_smp/src/txe_semaphore_put.c
+"${CC}" ${TARGET_FLAGS} -c -g -mcpu=cortex-a5 -I../../../../common_smp/inc -I../inc ../../../../common_smp/src/txe_semaphore_put_notify.c
+"${CC}" ${TARGET_FLAGS} -c -g -mcpu=cortex-a5 -I../../../../common_smp/inc -I../inc ../../../../common_smp/src/txe_thread_create.c
+"${CC}" ${TARGET_FLAGS} -c -g -mcpu=cortex-a5 -I../../../../common_smp/inc -I../inc ../../../../common_smp/src/txe_thread_delete.c
+"${CC}" ${TARGET_FLAGS} -c -g -mcpu=cortex-a5 -I../../../../common_smp/inc -I../inc ../../../../common_smp/src/txe_thread_entry_exit_notify.c
+"${CC}" ${TARGET_FLAGS} -c -g -mcpu=cortex-a5 -I../../../../common_smp/inc -I../inc ../../../../common_smp/src/txe_thread_info_get.c
+"${CC}" ${TARGET_FLAGS} -c -g -mcpu=cortex-a5 -I../../../../common_smp/inc -I../inc ../../../../common_smp/src/txe_thread_preemption_change.c
+"${CC}" ${TARGET_FLAGS} -c -g -mcpu=cortex-a5 -I../../../../common_smp/inc -I../inc ../../../../common_smp/src/txe_thread_priority_change.c
+"${CC}" ${TARGET_FLAGS} -c -g -mcpu=cortex-a5 -I../../../../common_smp/inc -I../inc ../../../../common_smp/src/txe_thread_relinquish.c
+"${CC}" ${TARGET_FLAGS} -c -g -mcpu=cortex-a5 -I../../../../common_smp/inc -I../inc ../../../../common_smp/src/txe_thread_reset.c
+"${CC}" ${TARGET_FLAGS} -c -g -mcpu=cortex-a5 -I../../../../common_smp/inc -I../inc ../../../../common_smp/src/txe_thread_resume.c
+"${CC}" ${TARGET_FLAGS} -c -g -mcpu=cortex-a5 -I../../../../common_smp/inc -I../inc ../../../../common_smp/src/txe_thread_suspend.c
+"${CC}" ${TARGET_FLAGS} -c -g -mcpu=cortex-a5 -I../../../../common_smp/inc -I../inc ../../../../common_smp/src/txe_thread_terminate.c
+"${CC}" ${TARGET_FLAGS} -c -g -mcpu=cortex-a5 -I../../../../common_smp/inc -I../inc ../../../../common_smp/src/txe_thread_time_slice_change.c
+"${CC}" ${TARGET_FLAGS} -c -g -mcpu=cortex-a5 -I../../../../common_smp/inc -I../inc ../../../../common_smp/src/txe_thread_wait_abort.c
+"${CC}" ${TARGET_FLAGS} -c -g -mcpu=cortex-a5 -I../../../../common_smp/inc -I../inc ../../../../common_smp/src/txe_timer_activate.c
+"${CC}" ${TARGET_FLAGS} -c -g -mcpu=cortex-a5 -I../../../../common_smp/inc -I../inc ../../../../common_smp/src/txe_timer_change.c
+"${CC}" ${TARGET_FLAGS} -c -g -mcpu=cortex-a5 -I../../../../common_smp/inc -I../inc ../../../../common_smp/src/txe_timer_create.c
+"${CC}" ${TARGET_FLAGS} -c -g -mcpu=cortex-a5 -I../../../../common_smp/inc -I../inc ../../../../common_smp/src/txe_timer_deactivate.c
+"${CC}" ${TARGET_FLAGS} -c -g -mcpu=cortex-a5 -I../../../../common_smp/inc -I../inc ../../../../common_smp/src/txe_timer_delete.c
+"${CC}" ${TARGET_FLAGS} -c -g -mcpu=cortex-a5 -I../../../../common_smp/inc -I../inc ../../../../common_smp/src/txe_timer_info_get.c
+"${CC}" ${TARGET_FLAGS} -c -g -mcpu=cortex-a5 -I../../../../common_smp/inc -I../inc ../../../../common_smp/src/tx_thread_smp_current_state_set.c
+"${CC}" ${TARGET_FLAGS} -c -g -mcpu=cortex-a5 -I../../../../common_smp/inc -I../inc ../../../../common_smp/src/tx_thread_smp_debug_entry_insert.c
+"${CC}" ${TARGET_FLAGS} -c -g -mcpu=cortex-a5 -I../../../../common_smp/inc -I../inc ../../../../common_smp/src/tx_thread_smp_high_level_initialize.c
+"${CC}" ${TARGET_FLAGS} -c -g -mcpu=cortex-a5 -I../../../../common_smp/inc -I../inc ../../../../common_smp/src/tx_thread_smp_rebalance_execute_list.c
+"${CC}" ${TARGET_FLAGS} -c -g -mcpu=cortex-a5 -I../../../../common_smp/inc -I../inc ../../../../common_smp/src/tx_thread_smp_core_exclude.c
+"${CC}" ${TARGET_FLAGS} -c -g -mcpu=cortex-a5 -I../../../../common_smp/inc -I../inc ../../../../common_smp/src/tx_thread_smp_core_exclude_get.c
+"${CC}" ${TARGET_FLAGS} -c -g -mcpu=cortex-a5 -I../../../../common_smp/inc -I../inc ../../../../common_smp/src/tx_timer_smp_core_exclude.c
+"${CC}" ${TARGET_FLAGS} -c -g -mcpu=cortex-a5 -I../../../../common_smp/inc -I../inc ../../../../common_smp/src/tx_timer_smp_core_exclude_get.c
+"${CC}" ${TARGET_FLAGS} -c -g -mcpu=cortex-a5 -I../../../../common_smp/inc -I../inc ../../../../common_smp/src/tx_thread_smp_utilities.c
+"${AR}" -r tx.a tx_thread_stack_build.o tx_thread_schedule.o tx_thread_system_return.o tx_thread_context_save.o tx_thread_context_restore.o tx_timer_interrupt.o tx_thread_interrupt_control.o
+"${AR}" -r tx.a tx_initialize_low_level.o tx_thread_interrupt_disable.o
+"${AR}" -r tx.a tx_thread_interrupt_restore.o tx_thread_irq_nesting_end.o tx_thread_irq_nesting_start.o
+"${AR}" -r tx.a tx_block_allocate.o tx_block_pool_cleanup.o tx_block_pool_create.o tx_block_pool_delete.o tx_block_pool_info_get.o
+"${AR}" -r tx.a tx_block_pool_initialize.o tx_block_pool_performance_info_get.o tx_block_pool_performance_system_info_get.o tx_block_pool_prioritize.o
+"${AR}" -r tx.a tx_block_release.o tx_byte_allocate.o tx_byte_pool_cleanup.o tx_byte_pool_create.o tx_byte_pool_delete.o tx_byte_pool_info_get.o
+"${AR}" -r tx.a tx_byte_pool_initialize.o tx_byte_pool_performance_info_get.o tx_byte_pool_performance_system_info_get.o tx_byte_pool_prioritize.o
+"${AR}" -r tx.a tx_byte_pool_search.o tx_byte_release.o tx_event_flags_cleanup.o tx_event_flags_create.o tx_event_flags_delete.o tx_event_flags_get.o
+"${AR}" -r tx.a tx_event_flags_info_get.o tx_event_flags_initialize.o tx_event_flags_performance_info_get.o tx_event_flags_performance_system_info_get.o
+"${AR}" -r tx.a tx_event_flags_set.o tx_event_flags_set_notify.o tx_initialize_high_level.o tx_initialize_kernel_enter.o tx_initialize_kernel_setup.o
+"${AR}" -r tx.a tx_mutex_cleanup.o tx_mutex_create.o tx_mutex_delete.o tx_mutex_get.o tx_mutex_info_get.o tx_mutex_initialize.o tx_mutex_performance_info_get.o
+"${AR}" -r tx.a tx_mutex_performance_system_info_get.o tx_mutex_prioritize.o tx_mutex_priority_change.o tx_mutex_put.o tx_queue_cleanup.o tx_queue_create.o
+"${AR}" -r tx.a tx_queue_delete.o tx_queue_flush.o tx_queue_front_send.o tx_queue_info_get.o tx_queue_initialize.o tx_queue_performance_info_get.o
+"${AR}" -r tx.a tx_queue_performance_system_info_get.o tx_queue_prioritize.o tx_queue_receive.o tx_queue_send.o tx_queue_send_notify.o tx_semaphore_ceiling_put.o
+"${AR}" -r tx.a tx_semaphore_cleanup.o tx_semaphore_create.o tx_semaphore_delete.o tx_semaphore_get.o tx_semaphore_info_get.o tx_semaphore_initialize.o
+"${AR}" -r tx.a tx_semaphore_performance_info_get.o tx_semaphore_performance_system_info_get.o tx_semaphore_prioritize.o tx_semaphore_put.o tx_semaphore_put_notify.o
+"${AR}" -r tx.a tx_thread_create.o tx_thread_delete.o tx_thread_entry_exit_notify.o tx_thread_identify.o tx_thread_info_get.o tx_thread_initialize.o
+"${AR}" -r tx.a tx_thread_performance_info_get.o tx_thread_performance_system_info_get.o tx_thread_preemption_change.o tx_thread_priority_change.o tx_thread_relinquish.o
+"${AR}" -r tx.a tx_thread_reset.o tx_thread_resume.o tx_thread_shell_entry.o tx_thread_sleep.o tx_thread_stack_analyze.o tx_thread_stack_error_handler.o
+"${AR}" -r tx.a tx_thread_stack_error_notify.o tx_thread_suspend.o tx_thread_system_preempt_check.o tx_thread_system_resume.o tx_thread_system_suspend.o
+"${AR}" -r tx.a tx_thread_terminate.o tx_thread_time_slice.o tx_thread_time_slice_change.o tx_thread_timeout.o tx_thread_wait_abort.o tx_time_get.o
+"${AR}" -r tx.a tx_time_set.o tx_timer_activate.o tx_timer_change.o tx_timer_create.o tx_timer_deactivate.o tx_timer_delete.o tx_timer_expiration_process.o
+"${AR}" -r tx.a tx_timer_info_get.o tx_timer_initialize.o tx_timer_performance_info_get.o tx_timer_performance_system_info_get.o tx_timer_system_activate.o
+"${AR}" -r tx.a tx_timer_system_deactivate.o tx_timer_thread_entry.o tx_trace_enable.o tx_trace_disable.o tx_trace_initialize.o tx_trace_interrupt_control.o
+"${AR}" -r tx.a tx_trace_isr_enter_insert.o tx_trace_isr_exit_insert.o tx_trace_object_register.o tx_trace_object_unregister.o tx_trace_user_event_insert.o
+"${AR}" -r tx.a tx_trace_buffer_full_notify.o tx_trace_event_filter.o tx_trace_event_unfilter.o
+"${AR}" -r tx.a txe_block_allocate.o txe_block_pool_create.o txe_block_pool_delete.o txe_block_pool_info_get.o txe_block_pool_prioritize.o txe_block_release.o
+"${AR}" -r tx.a txe_byte_allocate.o txe_byte_pool_create.o txe_byte_pool_delete.o txe_byte_pool_info_get.o txe_byte_pool_prioritize.o txe_byte_release.o
+"${AR}" -r tx.a txe_event_flags_create.o txe_event_flags_delete.o txe_event_flags_get.o txe_event_flags_info_get.o txe_event_flags_set.o
+"${AR}" -r tx.a txe_event_flags_set_notify.o txe_mutex_create.o txe_mutex_delete.o txe_mutex_get.o txe_mutex_info_get.o txe_mutex_prioritize.o
+"${AR}" -r tx.a txe_mutex_put.o txe_queue_create.o txe_queue_delete.o txe_queue_flush.o txe_queue_front_send.o txe_queue_info_get.o txe_queue_prioritize.o
+"${AR}" -r tx.a txe_queue_receive.o txe_queue_send.o txe_queue_send_notify.o txe_semaphore_ceiling_put.o txe_semaphore_create.o txe_semaphore_delete.o
+"${AR}" -r tx.a txe_semaphore_get.o txe_semaphore_info_get.o txe_semaphore_prioritize.o txe_semaphore_put.o txe_semaphore_put_notify.o txe_thread_create.o
+"${AR}" -r tx.a txe_thread_delete.o txe_thread_entry_exit_notify.o txe_thread_info_get.o txe_thread_preemption_change.o txe_thread_priority_change.o
+"${AR}" -r tx.a txe_thread_relinquish.o txe_thread_reset.o txe_thread_resume.o txe_thread_suspend.o txe_thread_terminate.o txe_thread_time_slice_change.o
+"${AR}" -r tx.a txe_thread_wait_abort.o txe_timer_activate.o txe_timer_change.o txe_timer_create.o txe_timer_deactivate.o txe_timer_delete.o txe_timer_info_get.o
+"${AR}" -r tx.a tx_thread_smp_current_state_set.o tx_thread_smp_debug_entry_insert.o tx_thread_smp_high_level_initialize.o
+"${AR}" -r tx.a tx_thread_smp_rebalance_execute_list.o tx_thread_smp_core_exclude.o tx_thread_smp_core_exclude_get.o
+"${AR}" -r tx.a tx_timer_smp_core_exclude.o tx_timer_smp_core_exclude_get.o tx_thread_smp_utilities.o
+"${AR}" -r tx.a tx_thread_smp_core_get.o tx_thread_smp_core_preempt.o tx_thread_smp_current_state_get.o tx_thread_smp_current_thread_get.o tx_thread_smp_initialize_wait.o
+"${AR}" -r tx.a tx_thread_smp_low_level_initialize.o tx_thread_smp_protect.o tx_thread_smp_time_get.o tx_thread_smp_unprotect.o
diff --git a/ports_smp/cortex_a5_smp/gnu/example_build/build_threadx_sample.sh b/ports_smp/cortex_a5_smp/gnu/example_build/build_threadx_sample.sh
new file mode 100755
index 00000000..7ed4946e
--- /dev/null
+++ b/ports_smp/cortex_a5_smp/gnu/example_build/build_threadx_sample.sh
@@ -0,0 +1,56 @@
+#!/bin/sh
+##############################################################################
+# 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.
+#
+# SPDX-License-Identifier: MIT
+##############################################################################
+
+set -e
+cd "$(dirname "$0")"
+
+# this script builds the ThreadX sample image for the Cortex-A5 SMP port using
+# GNU toolchain or llvm/clang toolchain (defaults to GNU).
+: "${TOOLCHAIN:=gnu}"
+case "${TOOLCHAIN}" in
+ gnu)
+ CC="arm-none-eabi-gcc"
+ TARGET_FLAGS=""
+ # GNU and Clang use different driver syntax for selecting the program's
+ # entry-point symbol.
+ ENTRY_FLAG="-e Vectors"
+ # Bare-metal C libraries require syscall support. GNU uses newlib's nosys stubs
+ # while ATFE requires a semihost library.
+ SYSCALL_LIB="--specs=nosys.specs"
+ ;;
+ atfe)
+ CC="${ATFE_CLANG:-clang}"
+ TARGET_FLAGS="--target=arm-none-eabi"
+ ENTRY_FLAG="-Wl,--entry=Vectors"
+ SYSCALL_LIB="-lsemihost"
+ ;;
+ *)
+ echo "Unknown TOOLCHAIN: ${TOOLCHAIN}" >&2
+ exit 1
+ ;;
+esac
+
+"${CC}" ${TARGET_FLAGS} -c -g -I../../../../common_smp/inc -I../inc -mcpu=cortex-a5 sample_threadx.c
+"${CC}" ${TARGET_FLAGS} -c -g -mcpu=cortex-a5 startup.S
+"${CC}" ${TARGET_FLAGS} -c -g -mcpu=cortex-a5 crt0.S
+"${CC}" ${TARGET_FLAGS} -c -g -mcpu=cortex-a5 MP_GIC.S
+"${CC}" ${TARGET_FLAGS} -c -g -mcpu=cortex-a5 MP_SCU.S
+"${CC}" ${TARGET_FLAGS} -c -g -mcpu=cortex-a5 MP_Mutexes.S
+"${CC}" ${TARGET_FLAGS} -c -g -mcpu=cortex-a5 MP_PrivateTimer.S
+"${CC}" ${TARGET_FLAGS} -c -g -mcpu=cortex-a5 v7.S
+"${CC}" ${TARGET_FLAGS} -g -mcpu=cortex-a5 -nostartfiles \
+ -T sample_threadx.ld \
+ ${ENTRY_FLAG} \
+ ${SYSCALL_LIB} \
+ -o sample_threadx.out \
+ MP_PrivateTimer.o MP_GIC.o MP_Mutexes.o MP_SCU.o \
+ sample_threadx.o startup.o crt0.o v7.o tx.a \
+ -Wl,-M > sample_threadx.map
diff --git a/ports_smp/cortex_a5_smp/gnu/example_build/crt0.S b/ports_smp/cortex_a5_smp/gnu/example_build/crt0.S
new file mode 100644
index 00000000..abc817d5
--- /dev/null
+++ b/ports_smp/cortex_a5_smp/gnu/example_build/crt0.S
@@ -0,0 +1,101 @@
+
+ .syntax unified
+#if defined(THUMB_MODE)
+ .thumb
+#else
+ .arm
+#endif
+
+/* .text is used instead of .section .text so it works with arm-aout too. */
+ .text
+ .align 0
+
+#if defined(THUMB_MODE)
+ .thumb_func
+#endif
+ .global _mainCRTStartup
+_mainCRTStartup:
+#if defined(THUMB_MODE)
+ .thumb_func
+#endif
+ .global _start
+_start:
+#if defined(THUMB_MODE)
+ .thumb_func
+#endif
+ .global start
+start:
+
+/* Start by setting up a stack */
+ /* Set up the stack pointer to a fixed value */
+ ldr r3, .LC0
+ mov sp, r3
+ /* Setup a default stack-limit in case the code has been
+ compiled with "-mapcs-stack-check". Hard-wiring this value
+ is not ideal, since there is currently no support for
+ checking that the heap and stack have not collided, or that
+ this default 64k is enough for the program being executed.
+ However, it ensures that this simple crt0 world will not
+ immediately cause an overflow event: */
+ sub sl, sp, #64 << 10 /* Still assumes 256bytes below sl */
+ mov a2, #0 /* Second arg: fill value */
+ mov fp, a2 /* Null frame pointer */
+ mov r7, a2 /* Null frame pointer for Thumb */
+
+ ldr a1, .LC1 /* First arg: start of memory block */
+ ldr a3, .LC2
+ sub a3, a3, a1 /* Third arg: length of block */
+
+
+
+ bl memset
+ mov r0, #0 /* no arguments */
+ mov r1, #0 /* no argv either */
+#ifdef __USES_INITFINI__
+ /* Some arm/elf targets use the .init and .fini sections
+ to create constructors and destructors, and for these
+ targets we need to call the _init function and arrange
+ for _fini to be called at program exit. */
+ mov r4, r0
+ mov r5, r1
+/* ldr r0, .Lfini */
+ bl atexit
+/* bl init */
+ mov r0, r4
+ mov r1, r5
+#endif
+ bl main
+
+ bl exit /* Should not return. */
+
+
+ /* For Thumb, constants must be after the code since only
+ positive offsets are supported for PC relative addresses. */
+
+ .align 0
+.LC0:
+.LC1:
+ .word __bss_start__
+.LC2:
+ .word __bss_end__
+/*
+#ifdef __USES_INITFINI__
+.Lfini:
+ .word _fini
+#endif */
+ /* Return ... */
+ bx lr
+
+ .global _fini
+ .type _fini,function
+_fini:
+ BX lr // Return to caller
+
+/* Workspace for Angel calls. */
+ .data
+/* Data returned by monitor SWI. */
+.global __stack_base__
+HeapBase: .word 0
+HeapLimit: .word 0
+__stack_base__: .word 0
+StackLimit: .word 0
diff --git a/ports_smp/cortex_a5_smp/gnu/example_build/tx_initialize_low_level.s b/ports_smp/cortex_a5_smp/gnu/example_build/tx_initialize_low_level.S
index 56066e5d..56066e5d 100644
--- a/ports_smp/cortex_a5_smp/gnu/example_build/tx_initialize_low_level.s
+++ b/ports_smp/cortex_a5_smp/gnu/example_build/tx_initialize_low_level.S
diff --git a/ports_smp/cortex_a5_smp/gnu/inc/tx_port.h b/ports_smp/cortex_a5_smp/gnu/inc/tx_port.h
index deb71768..b60e132f 100644
--- a/ports_smp/cortex_a5_smp/gnu/inc/tx_port.h
+++ b/ports_smp/cortex_a5_smp/gnu/inc/tx_port.h
@@ -391,7 +391,7 @@ void tx_thread_vfp_disable(void);
#ifdef TX_THREAD_INIT
CHAR _tx_version_id[] =
- "(c) 2024 Microsoft Corp. (c) 2026-present Eclipse ThreadX contributors. * ThreadX SMP/Cortex-A5/GNU Version 6.5.1.202602a *";
+ "(c) 2024 Microsoft Corp. (c) 2026-present Eclipse ThreadX contributors. * ThreadX SMP/Cortex-A5/GNU Version 6.5.2.202603 *";
#else
extern CHAR _tx_version_id[];
#endif
diff --git a/ports_smp/cortex_a5_smp/gnu/src/tx_thread_context_restore.S b/ports_smp/cortex_a5_smp/gnu/src/tx_thread_context_restore.S
index 53ca2cc2..e320303b 100644
--- a/ports_smp/cortex_a5_smp/gnu/src/tx_thread_context_restore.S
+++ b/ports_smp/cortex_a5_smp/gnu/src/tx_thread_context_restore.S
@@ -1,5 +1,6 @@
@/***************************************************************************
@ * Copyright (c) 2024 Microsoft Corporation
+@ * 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
@@ -7,6 +8,7 @@
@ *
@ * SPDX-License-Identifier: MIT
@ **************************************************************************/
+@ Portions of this file were generated with AI assistance.
@
@
@/**************************************************************************/
@@ -29,8 +31,6 @@
@#include "tx_thread.h"
@#include "tx_timer.h"
@
-@/* Include macros for modifying the wait list. */
-#include "tx_thread_smp_protection_wait_list_macros.h"
#ifdef TX_ENABLE_FIQ_SUPPORT
DISABLE_INTS = 0xC0 @ Disable IRQ & FIQ interrupts
@@ -51,11 +51,6 @@ SVC_MODE = 0x93 @ SVC mode
.global _tx_thread_preempt_disable
.global _tx_timer_interrupt_active
.global _tx_thread_smp_protection
- .global _tx_thread_smp_protect_wait_counts
- .global _tx_thread_smp_protect_wait_list
- .global _tx_thread_smp_protect_wait_list_lock_protect_in_force
- .global _tx_thread_smp_protect_wait_list_tail
- .global _tx_thread_smp_protect_wait_list_size
#ifdef TX_ENABLE_EXECUTION_CHANGE_NOTIFY
.global _tx_execution_isr_exit
#endif
@@ -198,77 +193,6 @@ __tx_thread_no_preempt_restore:
@ {
@
__tx_thread_preempt_restore:
-@
-@ /* Was the thread being preempted waiting for the lock? */
-@ if (_tx_thread_smp_protect_wait_counts[this_core] != 0)
-@ {
-@
- LDR r1, =_tx_thread_smp_protect_wait_counts @ Load waiting count list
- LDR r2, [r1, r10, LSL #2] @ Load waiting value for this core
- CMP r2, #0
- BEQ _nobody_waiting_for_lock @ Is the core waiting for the lock?
-@
-@ /* Do we not have the lock? This means the ISR never got the inter-core lock. */
-@ if (_tx_thread_smp_protection.tx_thread_smp_protect_owned != this_core)
-@ {
-@
- LDR r1, =_tx_thread_smp_protection @ Load address of protection structure
- LDR r2, [r1, #8] @ Pickup the owning core
- CMP r10, r2 @ Compare our core to the owning core
- BEQ _this_core_has_lock @ Do we have the lock?
-@
-@ /* We don't have the lock. This core should be in the list. Remove it. */
-@ _tx_thread_smp_protect_wait_list_remove(this_core);
-@
- MOV r0, r10 @ Move the core ID to r0 for the macro
- _tx_thread_smp_protect_wait_list_remove @ Call macro to remove core from the list
- B _nobody_waiting_for_lock @ Leave
-@
-@ }
-@ else
-@ {
-@ /* We have the lock. This means the ISR got the inter-core lock, but
-@ never released it because it saw that there was someone waiting.
-@ Note this core is not in the list. */
-@
-_this_core_has_lock:
-@
-@ /* We're no longer waiting. Note that this should be zero since this happens during thread preemption. */
-@ _tx_thread_smp_protect_wait_counts[core]--;
-@
- LDR r1, =_tx_thread_smp_protect_wait_counts @ Load waiting count list
- LDR r2, [r1, r10, LSL #2] @ Load waiting value for this core
- SUB r2, r2, #1 @ Decrement waiting value. Should be zero now
- STR r2, [r1, r10, LSL #2] @ Store new waiting value
-@
-@ /* Now release the inter-core lock. */
-@
-@ /* Set protected core as invalid. */
-@ _tx_thread_smp_protection.tx_thread_smp_protect_core = 0xFFFFFFFF;
-@
- LDR r1, =_tx_thread_smp_protection @ Load address of protection structure
- MOV r2, #0xFFFFFFFF @ Build invalid value
- STR r2, [r1, #8] @ Mark the protected core as invalid
- DMB @ Ensure that accesses to shared resource have completed
-@
-@ /* Release protection. */
-@ _tx_thread_smp_protection.tx_thread_smp_protect_in_force = 0;
-@
- MOV r2, #0 @ Build release protection value
- STR r2, [r1, #0] @ Release the protection
- DSB ISH @ To ensure update of the protection occurs before other CPUs awake
-@
-@ /* Wake up waiting processors. Note interrupts are already enabled. */
-@
-#ifdef TX_ENABLE_WFE
- SEV @ Send event to other CPUs
-#endif
-@
-@ }
-@ }
-@
-
-_nobody_waiting_for_lock:
LDMIA sp!, {r3, r10, r12, lr} @ Recover temporarily saved registers
MOV r1, lr @ Save lr (point of interrupt)
diff --git a/ports_smp/cortex_a5_smp/gnu/src/tx_thread_context_save.S b/ports_smp/cortex_a5_smp/gnu/src/tx_thread_context_save.S
index 3148c0f5..299d5a0d 100644
--- a/ports_smp/cortex_a5_smp/gnu/src/tx_thread_context_save.S
+++ b/ports_smp/cortex_a5_smp/gnu/src/tx_thread_context_save.S
@@ -1,5 +1,6 @@
@/***************************************************************************
@ * Copyright (c) 2024 Microsoft Corporation
+@ * Copyright (c) 2026-present Eclipse ThreadX contributors
@ *
@ * This program and the accompanying materials are made available under the
@ * terms of the MIT License which is available at
@@ -8,6 +9,7 @@
@ * SPDX-License-Identifier: MIT
@ **************************************************************************/
@
+@ Portions of this file were generated with AI assistance.
@
@/**************************************************************************/
@/**************************************************************************/
@@ -147,11 +149,11 @@ __tx_thread_not_nested_save:
BEQ __tx_thread_idle_system_save @ If so, interrupt occurred in
@ scheduling loop - nothing needs saving!
@
-@ /* Save the current stack pointer in the thread's control block. */
-@ _tx_thread_current_ptr[core] -> tx_thread_stack_ptr = sp;
-@
-@ /* Switch to the system stack. */
-@ sp = _tx_thread_system_stack_ptr;
+@ /* This routine runs in IRQ mode on this core's banked IRQ stack, which
+@ serves as the system stack on this architecture, so there is no stack
+@ switch to perform here. The thread's stack pointer is saved in its
+@ control block by _tx_thread_context_restore, and only when the
+@ interrupt results in preemption. */
@
MOV r10, #0 @ Clear stack limit
diff --git a/ports_smp/cortex_a5_smp/gnu/src/tx_thread_schedule.S b/ports_smp/cortex_a5_smp/gnu/src/tx_thread_schedule.S
index 00f254dd..5ef6af30 100644
--- a/ports_smp/cortex_a5_smp/gnu/src/tx_thread_schedule.S
+++ b/ports_smp/cortex_a5_smp/gnu/src/tx_thread_schedule.S
@@ -1,5 +1,6 @@
@/***************************************************************************
@ * Copyright (c) 2024 Microsoft Corporation
+@ * 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
@@ -8,6 +9,8 @@
@ * SPDX-License-Identifier: MIT
@ **************************************************************************/
@
+@ Portions of this file were generated with AI assistance.
+@
@
@/**************************************************************************/
@/**************************************************************************/
@@ -166,6 +169,7 @@ _tx_thread_ready_for_execution:
LDR r2, =_tx_thread_current_ptr @ Pickup address of current thread
ADD r2, r2, r12 @ Build index into the current thread array
STR r0, [r2, #0] @ Setup current thread pointer
+ DMB @ Ensure the current thread pointer write completes
@
@ /* In the time between reading the execute pointer and assigning
@ it to the current pointer, the execute pointer was changed by
diff --git a/ports_smp/cortex_a5_smp/gnu/src/tx_thread_smp_protect.S b/ports_smp/cortex_a5_smp/gnu/src/tx_thread_smp_protect.S
index db0a2525..560fa8df 100644
--- a/ports_smp/cortex_a5_smp/gnu/src/tx_thread_smp_protect.S
+++ b/ports_smp/cortex_a5_smp/gnu/src/tx_thread_smp_protect.S
@@ -1,5 +1,6 @@
@/***************************************************************************
@ * Copyright (c) 2024 Microsoft Corporation
+@ * 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
@@ -7,6 +8,7 @@
@ *
@ * SPDX-License-Identifier: MIT
@ **************************************************************************/
+@ Portions of this file were generated with AI assistance.
@
@
@/**************************************************************************/
@@ -31,17 +33,9 @@
@
@
-@/* Include macros for modifying the wait list. */
-#include "tx_thread_smp_protection_wait_list_macros.h"
.global _tx_thread_current_ptr
.global _tx_thread_smp_protection
- .global _tx_thread_smp_protect_wait_counts
- .global _tx_thread_smp_protect_wait_list
- .global _tx_thread_smp_protect_wait_list_lock_protect_in_force
- .global _tx_thread_smp_protect_wait_list_head
- .global _tx_thread_smp_protect_wait_list_tail
- .global _tx_thread_smp_protect_wait_list_size
.arm
.text
@@ -82,12 +76,12 @@
.global _tx_thread_smp_protect
.type _tx_thread_smp_protect,function
_tx_thread_smp_protect:
-
- PUSH {r4-r6} @ Save registers we'll be using
+@VOID _tx_thread_smp_protect(VOID)
+@{
@
@ /* Disable interrupts so we don't get preempted. */
@
- MRS r0, CPSR @ Pickup current CPSR
+ MRS r3, CPSR @ Pickup current CPSR
#ifdef TX_ENABLE_FIQ_SUPPORT
CPSID if @ Disable IRQ and FIQ interrupts
@@ -95,270 +89,96 @@ _tx_thread_smp_protect:
CPSID i @ Disable IRQ interrupts
#endif
@
+@ /* Pickup the CPU ID. */
+@
+ MRC p15, 0, r2, c0, c0, 5 @ Read CPU ID register
+ AND r2, r2, #0x03 @ Mask off, leaving the CPU ID field
+@
@ /* Do we already have protection? */
@ if (this_core == _tx_thread_smp_protection.tx_thread_smp_protect_core)
@ {
@
- MRC p15, 0, r1, c0, c0, 5 @ Read CPU ID register
- AND r1, r1, #0x03 @ Mask off, leaving the CPU ID field
- LDR r2, =_tx_thread_smp_protection @ Build address to protection structure
- LDR r3, [r2, #8] @ Pickup the owning core
- CMP r1, r3 @ Is it not this core?
- BNE _protection_not_owned @ No, the protection is not already owned
-@
-@ /* We already have protection. */
-@
-@ /* Increment the protection count. */
-@ _tx_thread_smp_protection.tx_thread_smp_protect_count++;
+ LDR r0, =_tx_thread_smp_protection @ Build address to protection structure
+ LDR r1, [r0, #8] @ Pickup the owning core
+ CMP r1, r2 @ Is it this core?
+ BEQ _owned @ Yes, the protection is already owned
@
- LDR r3, [r2, #12] @ Pickup ownership count
- ADD r3, r3, #1 @ Increment ownership count
- STR r3, [r2, #12] @ Store ownership count
- DMB
-
- B _return
-
-_protection_not_owned:
+@ }
@
@ /* Is the lock available? */
@ if (_tx_thread_smp_protection.tx_thread_smp_protect_in_force == 0)
@ {
@
- LDREX r3, [r2, #0] @ Pickup the protection flag
- CMP r3, #0
- BNE _start_waiting @ No, protection not available
-@
-@ /* Is the list empty? */
-@ if (_tx_thread_smp_protect_wait_list_head == _tx_thread_smp_protect_wait_list_tail)
-@ {
-@
- LDR r3, =_tx_thread_smp_protect_wait_list_head
- LDR r3, [r3]
- LDR r4, =_tx_thread_smp_protect_wait_list_tail
- LDR r4, [r4]
- CMP r3, r4
- BNE _list_not_empty
-@
-@ /* Try to get the lock. */
-@ if (write_exclusive(&_tx_thread_smp_protection.tx_thread_smp_protect_in_force, 1) == SUCCESS)
-@ {
-@
- MOV r3, #1 @ Build lock value
- STREX r4, r3, [r2, #0] @ Attempt to get the protection
- CMP r4, #0
- BNE _start_waiting @ Did it fail?
-@
-@ /* We got the lock! */
-@ _tx_thread_smp_protect_lock_got();
-@
- DMB @ Ensure write to protection finishes
- _tx_thread_smp_protect_lock_got @ Call the lock got function
-
- B _return
-
-_list_not_empty:
-@
-@ /* Are we at the front of the list? */
-@ if (this_core == _tx_thread_smp_protect_wait_list[_tx_thread_smp_protect_wait_list_head])
-@ {
-@
- LDR r3, =_tx_thread_smp_protect_wait_list_head @ Get the address of the head
- LDR r3, [r3] @ Get the value of the head
- LDR r4, =_tx_thread_smp_protect_wait_list @ Get the address of the list
- LDR r4, [r4, r3, LSL #2] @ Get the value at the head index
-
- CMP r1, r4
- BNE _start_waiting
-@
-@ /* Is the lock still available? */
-@ if (_tx_thread_smp_protection.tx_thread_smp_protect_in_force == 0)
-@ {
-@
- LDR r3, [r2, #0] @ Pickup the protection flag
- CMP r3, #0
- BNE _start_waiting @ No, protection not available
-@
-@ /* Get the lock. */
-@ _tx_thread_smp_protection.tx_thread_smp_protect_in_force = 1;
-@
- MOV r3, #1 @ Build lock value
- STR r3, [r2, #0] @ Store lock value
- DMB @
-@
-@ /* Got the lock. */
-@ _tx_thread_smp_protect_lock_got();
-@
- _tx_thread_smp_protect_lock_got
-@
-@ /* Remove this core from the wait list. */
-@ _tx_thread_smp_protect_remove_from_front_of_list();
-@
- _tx_thread_smp_protect_remove_from_front_of_list
-
- B _return
-
-_start_waiting:
-@
-@ /* For one reason or another, we didn't get the lock. */
-@
-@ /* Increment wait count. */
-@ _tx_thread_smp_protect_wait_counts[this_core]++;
-@
- LDR r3, =_tx_thread_smp_protect_wait_counts @ Load wait list counts
- LDR r4, [r3, r1, LSL #2] @ Load waiting value for this core
- ADD r4, r4, #1 @ Increment wait value
- STR r4, [r3, r1, LSL #2] @ Store new wait value
-@
-@ /* Have we not added ourselves to the list yet? */
-@ if (_tx_thread_smp_protect_wait_counts[this_core] == 1)
-@ {
-@
- CMP r4, #1
- BNE _already_in_list0 @ Is this core already waiting?
-@
-@ /* Add ourselves to the list. */
-@ _tx_thread_smp_protect_wait_list_add(this_core);
-@
- _tx_thread_smp_protect_wait_list_add @ Call macro to add ourselves to the list
+ LDREX r1, [r0] @ Pickup the protection flag
+ CMP r1, #0 @ Is it available?
+ BEQ _get_protection @ Yes, attempt to get the protection
@
@ }
@
-_already_in_list0:
-@
-@ /* Restore interrupts. */
+@ /* The protection is held elsewhere. Restore interrupts so this core can be
+@ preempted while it waits, then try the whole sequence again. */
@
- MSR CPSR_c, r0 @ Restore CPSR
+ MSR CPSR_c, r3 @ Restore CPSR
#ifdef TX_ENABLE_WFE
WFE @ Go into standby
#endif
-@
-@ /* We do this until we have the lock. */
-@ while (1)
-@ {
-@
-_try_to_get_lock:
-@
-@ /* Disable interrupts so we don't get preempted. */
-@
-#ifdef TX_ENABLE_FIQ_SUPPORT
- CPSID if @ Disable IRQ and FIQ interrupts
-#else
- CPSID i @ Disable IRQ interrupts
-#endif
+ B _tx_thread_smp_protect @ On waking, restart the protection attempt
- MRC p15, 0, r1, c0, c0, 5 @ Read CPU ID register
- AND r1, r1, #0x03 @ Mask off, leaving the CPU ID field
+_get_protection:
@
-@ /* Do we already have protection? */
-@ if (this_core == _tx_thread_smp_protection.tx_thread_smp_protect_core)
+@ /* Try to get the lock. */
+@ if (write_exclusive(&_tx_thread_smp_protection.tx_thread_smp_protect_in_force, 1) == SUCCESS)
@ {
@
- LDR r3, [r2, #8] @ Pickup the owning core
- CMP r3, r1 @ Is it this core?
- BEQ _got_lock_after_waiting @ Yes, the protection is already owned. This means
- @ an ISR preempted us and got protection
+ MOV r1, #1 @ Build lock value
+ STREX r2, r1, [r0] @ Attempt to get the protection
+ CMP r2, #0 @ Check whether the store succeeded (0 = success)
+ BEQ _got_protection @ Yes, we have the protection
@
@ }
@
-@ /* Are we at the front of the list? */
-@ if (this_core == _tx_thread_smp_protect_wait_list[_tx_thread_smp_protect_wait_list_head])
-@ {
+@ /* Another core beat us to it. Restore interrupts and try again. */
@
- LDR r3, =_tx_thread_smp_protect_wait_list_head @ Get the address of the head
- LDR r3, [r3] @ Get the value of the head
- LDR r4, =_tx_thread_smp_protect_wait_list @ Get the address of the list
- LDR r4, [r4, r3, LSL #2] @ Get the value at the head index
+ MSR CPSR_c, r3 @ Restore CPSR
+ B _tx_thread_smp_protect @ Try the whole process again
- CMP r1, r4
- BNE _did_not_get_lock
-@
-@ /* Is the lock still available? */
-@ if (_tx_thread_smp_protection.tx_thread_smp_protect_in_force == 0)
-@ {
-@
- LDR r3, [r2, #0] @ Pickup the protection flag
- CMP r3, #0
- BNE _did_not_get_lock @ No, protection not available
-@
-@ /* Get the lock. */
-@ _tx_thread_smp_protection.tx_thread_smp_protect_in_force = 1;
-@
- MOV r3, #1 @ Build lock value
- STR r3, [r2, #0] @ Store lock value
- DMB @
+_got_protection:
@
-@ /* Got the lock. */
-@ _tx_thread_smp_protect_lock_got();
+@ /* Got the lock. Record the owning core. */
+@ _tx_thread_smp_protection.tx_thread_smp_protect_core = this_core;
@
- _tx_thread_smp_protect_lock_got
-@
-@ /* Remove this core from the wait list. */
-@ _tx_thread_smp_protect_remove_from_front_of_list();
-@
- _tx_thread_smp_protect_remove_from_front_of_list
-
- B _got_lock_after_waiting
+ DMB @ Ensure the protection write completes before it is used
+ MRC p15, 0, r2, c0, c0, 5 @ Read CPU ID register
+ AND r2, r2, #0x03 @ Mask off, leaving the CPU ID field
+ STR r2, [r0, #8] @ Save the owning core
-_did_not_get_lock:
-@
-@ /* For one reason or another, we didn't get the lock. */
-@
-@ /* Were we removed from the list? This can happen if we're a thread
-@ and we got preempted. */
-@ if (_tx_thread_smp_protect_wait_counts[this_core] == 0)
-@ {
-@
- LDR r3, =_tx_thread_smp_protect_wait_counts @ Load wait list counts
- LDR r4, [r3, r1, LSL #2] @ Load waiting value for this core
- CMP r4, #0
- BNE _already_in_list1 @ Is this core already in the list?
-@
-@ /* Add ourselves to the list. */
-@ _tx_thread_smp_protect_wait_list_add(this_core);
-@
- _tx_thread_smp_protect_wait_list_add @ Call macro to add ourselves to the list
-@
-@ /* Our waiting count was also reset when we were preempted. Increment it again. */
-@ _tx_thread_smp_protect_wait_counts[this_core]++;
-@
- LDR r3, =_tx_thread_smp_protect_wait_counts @ Load wait list counts
- LDR r4, [r3, r1, LSL #2] @ Load waiting value for this core
- ADD r4, r4, #1 @ Increment wait value
- STR r4, [r3, r1, LSL #2] @ Store new wait value value
-@
-@ }
-@
-_already_in_list1:
-@
-@ /* Restore interrupts and try again. */
-@
- MSR CPSR_c, r0 @ Restore CPSR
-#ifdef TX_ENABLE_WFE
- WFE @ Go into standby
+#ifdef TX_MPCORE_DEBUG_ENABLE
+ LSL r2, r2, #2 @ Build offset to array indexes
+ LDR r1, =_tx_thread_current_ptr @ Pickup start of the current thread array
+ ADD r1, r1, r2 @ Build index into the current thread array
+ LDR r2, [r1] @ Pickup current thread for this core
+ STR r2, [r0, #4] @ Save current thread pointer
+ STR LR, [r0, #16] @ Save caller's return address
+ STR r3, [r0, #20] @ Save CPSR
#endif
- B _try_to_get_lock @ On waking, restart the protection attempt
-_got_lock_after_waiting:
+_owned:
@
-@ /* We're no longer waiting. */
-@ _tx_thread_smp_protect_wait_counts[this_core]--;
+@ /* Increment the protection count. */
+@ _tx_thread_smp_protection.tx_thread_smp_protect_count++;
@
- LDR r3, =_tx_thread_smp_protect_wait_counts @ Load waiting list
- LDR r4, [r3, r1, LSL #2] @ Load current wait value
- SUB r4, r4, #1 @ Decrement wait value
- STR r4, [r3, r1, LSL #2] @ Store new wait value value
+ LDR r1, [r0, #12] @ Pickup ownership count
+ ADD r1, r1, #1 @ Increment ownership count
+ STR r1, [r0, #12] @ Store new ownership count
+ DMB @
+ MOV r0, r3 @ Return the previous CPSR
@
-@ /* Restore link register and return. */
+@}
@
-_return:
-
- POP {r4-r6} @ Restore registers
-
#ifdef __THUMB_INTERWORK
BX lr @ Return to caller
#else
MOV pc, lr @ Return to caller
#endif
-
diff --git a/ports_smp/cortex_a5_smp/gnu/src/tx_thread_smp_protection_wait_list_macros.h b/ports_smp/cortex_a5_smp/gnu/src/tx_thread_smp_protection_wait_list_macros.h
deleted file mode 100644
index f1ad80e8..00000000
--- a/ports_smp/cortex_a5_smp/gnu/src/tx_thread_smp_protection_wait_list_macros.h
+++ /dev/null
@@ -1,309 +0,0 @@
-@/***************************************************************************
-@ * Copyright (c) 2024 Microsoft Corporation
-@ *
-@ * 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.
-@ *
-@ * SPDX-License-Identifier: MIT
-@ **************************************************************************/
-@
-@
-@/**************************************************************************/
-@/**************************************************************************/
-@/** */
-@/** ThreadX Component */
-@/** */
-@/** Thread - Low Level SMP Support */
-@/** */
-@/**************************************************************************/
-@/**************************************************************************/
-
- .macro _tx_thread_smp_protect_lock_got
-@
-@ /* Set the currently owned core. */
-@ _tx_thread_smp_protection.tx_thread_smp_protect_core = this_core;
-@
- STR r1, [r2, #8] @ Store this core
-@
-@ /* Increment the protection count. */
-@ _tx_thread_smp_protection.tx_thread_smp_protect_count++;
-@
- LDR r3, [r2, #12] @ Pickup ownership count
- ADD r3, r3, #1 @ Increment ownership count
- STR r3, [r2, #12] @ Store ownership count
- DMB
-
-#ifdef TX_MPCORE_DEBUG_ENABLE
- LSL r3, r1, #2 @ Build offset to array indexes
- LDR r4, =_tx_thread_current_ptr @ Pickup start of the current thread array
- ADD r4, r3, r4 @ Build index into the current thread array
- LDR r3, [r4] @ Pickup current thread for this core
- STR r3, [r2, #4] @ Save current thread pointer
- STR LR, [r2, #16] @ Save caller's return address
- STR r0, [r2, #20] @ Save CPSR
-#endif
-
- .endm
-
- .macro _tx_thread_smp_protect_remove_from_front_of_list
-@
-@ /* Remove ourselves from the list. */
-@ _tx_thread_smp_protect_wait_list[_tx_thread_smp_protect_wait_list_head++] = 0xFFFFFFFF;
-@
- MOV r3, #0xFFFFFFFF @ Build the invalid core value
- LDR r4, =_tx_thread_smp_protect_wait_list_head @ Get the address of the head
- LDR r5, [r4] @ Get the value of the head
- LDR r6, =_tx_thread_smp_protect_wait_list @ Get the address of the list
- STR r3, [r6, r5, LSL #2] @ Store the invalid core value
- ADD r5, r5, #1 @ Increment the head
-@
-@ /* Did we wrap? */
-@ if (_tx_thread_smp_protect_wait_list_head == TX_THREAD_SMP_MAX_CORES + 1)
-@ {
-@
- LDR r3, =_tx_thread_smp_protect_wait_list_size @ Load address of core list size
- LDR r3, [r3] @ Load the max cores value
- CMP r5, r3 @ Compare the head to it
- BNE _store_new_head\@ @ Are we at the max?
-@
-@ _tx_thread_smp_protect_wait_list_head = 0;
-@
- EOR r5, r5, r5 @ We're at the max. Set it to zero
-@
-@ }
-@
-_store_new_head\@:
-
- STR r5, [r4] @ Store the new head
-@
-@ /* We have the lock! */
-@ return;
-@
- .endm
-
-
- .macro _tx_thread_smp_protect_wait_list_lock_get
-@VOID _tx_thread_smp_protect_wait_list_lock_get()
-@{
-@ /* We do this until we have the lock. */
-@ while (1)
-@ {
-@
-_tx_thread_smp_protect_wait_list_lock_get__try_to_get_lock\@:
-@
-@ /* Is the list lock available? */
-@ _tx_thread_smp_protect_wait_list_lock_protect_in_force = load_exclusive(&_tx_thread_smp_protect_wait_list_lock_protect_in_force);
-@
- LDR r1, =_tx_thread_smp_protect_wait_list_lock_protect_in_force
- LDREX r2, [r1] @ Pickup the protection flag
-@
-@ if (protect_in_force == 0)
-@ {
-@
- CMP r2, #0
- BNE _tx_thread_smp_protect_wait_list_lock_get__try_to_get_lock\@ @ No, protection not available
-@
-@ /* Try to get the list. */
-@ int status = store_exclusive(&_tx_thread_smp_protect_wait_list_lock_protect_in_force, 1);
-@
- MOV r2, #1 @ Build lock value
- STREX r3, r2, [r1] @ Attempt to get the protection
-@
-@ if (status == SUCCESS)
-@
- CMP r3, #0
- BNE _tx_thread_smp_protect_wait_list_lock_get__try_to_get_lock\@ @ Did it fail? If so, try again.
-@
-@ /* We have the lock! */
-@ return;
-@
- .endm
-
-
- .macro _tx_thread_smp_protect_wait_list_add
-@VOID _tx_thread_smp_protect_wait_list_add(UINT new_core)
-@{
-@
-@ /* We're about to modify the list, so get the list lock. */
-@ _tx_thread_smp_protect_wait_list_lock_get();
-@
- PUSH {r1-r2}
-
- _tx_thread_smp_protect_wait_list_lock_get
-
- POP {r1-r2}
-@
-@ /* Add this core. */
-@ _tx_thread_smp_protect_wait_list[_tx_thread_smp_protect_wait_list_tail++] = new_core;
-@
- LDR r3, =_tx_thread_smp_protect_wait_list_tail @ Get the address of the tail
- LDR r4, [r3] @ Get the value of tail
- LDR r5, =_tx_thread_smp_protect_wait_list @ Get the address of the list
- STR r1, [r5, r4, LSL #2] @ Store the new core value
- ADD r4, r4, #1 @ Increment the tail
-@
-@ /* Did we wrap? */
-@ if (_tx_thread_smp_protect_wait_list_tail == _tx_thread_smp_protect_wait_list_size)
-@ {
-@
- LDR r5, =_tx_thread_smp_protect_wait_list_size @ Load max cores address
- LDR r5, [r5] @ Load max cores value
- CMP r4, r5 @ Compare max cores to tail
- BNE _tx_thread_smp_protect_wait_list_add__no_wrap\@ @ Did we wrap?
-@
-@ _tx_thread_smp_protect_wait_list_tail = 0;
-@
- MOV r4, #0
-@
-@ }
-@
-_tx_thread_smp_protect_wait_list_add__no_wrap\@:
-
- STR r4, [r3] @ Store the new tail value.
-@
-@ /* Release the list lock. */
-@ _tx_thread_smp_protect_wait_list_lock_protect_in_force = 0;
-@
- MOV r3, #0 @ Build lock value
- LDR r4, =_tx_thread_smp_protect_wait_list_lock_protect_in_force
- STR r3, [r4] @ Store the new value
-
- .endm
-
-
- .macro _tx_thread_smp_protect_wait_list_remove
-@VOID _tx_thread_smp_protect_wait_list_remove(UINT core)
-@{
-@
-@ /* Get the core index. */
-@ UINT core_index;
-@ for (core_index = 0;; core_index++)
-@
- EOR r1, r1, r1 @ Clear for 'core_index'
- LDR r2, =_tx_thread_smp_protect_wait_list @ Get the address of the list
-@
-@ {
-@
-_tx_thread_smp_protect_wait_list_remove__check_cur_core\@:
-@
-@ /* Is this the core? */
-@ if (_tx_thread_smp_protect_wait_list[core_index] == core)
-@ {
-@ break;
-@
- LDR r3, [r2, r1, LSL #2] @ Get the value at the current index
- CMP r3, r0 @ Did we find the core?
- BEQ _tx_thread_smp_protect_wait_list_remove__found_core\@
-@
-@ }
-@
- ADD r1, r1, #1 @ Increment cur index
- B _tx_thread_smp_protect_wait_list_remove__check_cur_core\@ @ Restart the loop
-@
-@ }
-@
-_tx_thread_smp_protect_wait_list_remove__found_core\@:
-@
-@ /* We're about to modify the list. Get the lock. We need the lock because another
-@ core could be simultaneously adding (a core is simultaneously trying to get
-@ the inter-core lock) or removing (a core is simultaneously being preempted,
-@ like what is currently happening). */
-@ _tx_thread_smp_protect_wait_list_lock_get();
-@
- PUSH {r1}
-
- _tx_thread_smp_protect_wait_list_lock_get
-
- POP {r1}
-@
-@ /* We remove by shifting. */
-@ while (core_index != _tx_thread_smp_protect_wait_list_tail)
-@ {
-@
-_tx_thread_smp_protect_wait_list_remove__compare_index_to_tail\@:
-
- LDR r2, =_tx_thread_smp_protect_wait_list_tail @ Load tail address
- LDR r2, [r2] @ Load tail value
- CMP r1, r2 @ Compare cur index and tail
- BEQ _tx_thread_smp_protect_wait_list_remove__removed\@
-@
-@ UINT next_index = core_index + 1;
-@
- MOV r2, r1 @ Move current index to next index register
- ADD r2, r2, #1 @ Add 1
-@
-@ if (next_index == _tx_thread_smp_protect_wait_list_size)
-@ {
-@
- LDR r3, =_tx_thread_smp_protect_wait_list_size
- LDR r3, [r3]
- CMP r2, r3
- BNE _tx_thread_smp_protect_wait_list_remove__next_index_no_wrap\@
-@
-@ next_index = 0;
-@
- MOV r2, #0
-@
-@ }
-@
-_tx_thread_smp_protect_wait_list_remove__next_index_no_wrap\@:
-@
-@ list_cores[core_index] = list_cores[next_index];
-@
- LDR r0, =_tx_thread_smp_protect_wait_list @ Get the address of the list
- LDR r3, [r0, r2, LSL #2] @ Get the value at the next index
- STR r3, [r0, r1, LSL #2] @ Store the value at the current index
-@
-@ core_index = next_index;
-@
- MOV r1, r2
-
- B _tx_thread_smp_protect_wait_list_remove__compare_index_to_tail\@
-@
-@ }
-@
-_tx_thread_smp_protect_wait_list_remove__removed\@:
-@
-@ /* Now update the tail. */
-@ if (_tx_thread_smp_protect_wait_list_tail == 0)
-@ {
-@
- LDR r0, =_tx_thread_smp_protect_wait_list_tail @ Load tail address
- LDR r1, [r0] @ Load tail value
- CMP r1, #0
- BNE _tx_thread_smp_protect_wait_list_remove__tail_not_zero\@
-@
-@ _tx_thread_smp_protect_wait_list_tail = _tx_thread_smp_protect_wait_list_size;
-@
- LDR r2, =_tx_thread_smp_protect_wait_list_size
- LDR r1, [r2]
-@
-@ }
-@
-_tx_thread_smp_protect_wait_list_remove__tail_not_zero\@:
-@
-@ _tx_thread_smp_protect_wait_list_tail--;
-@
- SUB r1, r1, #1
- STR r1, [r0] @ Store new tail value
-@
-@ /* Release the list lock. */
-@ _tx_thread_smp_protect_wait_list_lock_protect_in_force = 0;
-@
- MOV r0, #0 @ Build lock value
- LDR r1, =_tx_thread_smp_protect_wait_list_lock_protect_in_force @ Load lock address
- STR r0, [r1] @ Store the new value
-@
-@ /* We're no longer waiting. Note that this should be zero since, again,
-@ this function is only called when a thread preemption is occurring. */
-@ _tx_thread_smp_protect_wait_counts[core]--;
-@
- MRC p15, 0, r0, c0, c0, 5 @ Read CPU ID register
- AND r0, r0, #0x03 @ Mask off, leaving the CPU ID field
- LDR r1, =_tx_thread_smp_protect_wait_counts @ Load wait list counts
- LDR r2, [r1, r0, LSL #2] @ Load waiting value
- SUB r2, r2, #1 @ Subtract 1
- STR r2, [r1, r0, LSL #2] @ Store new waiting value
- .endm
-
diff --git a/ports_smp/cortex_a5_smp/gnu/src/tx_thread_smp_time_get.S b/ports_smp/cortex_a5_smp/gnu/src/tx_thread_smp_time_get.S
index 7e399690..f9ecf1b5 100644
--- a/ports_smp/cortex_a5_smp/gnu/src/tx_thread_smp_time_get.S
+++ b/ports_smp/cortex_a5_smp/gnu/src/tx_thread_smp_time_get.S
@@ -1,5 +1,6 @@
@/***************************************************************************
@ * Copyright (c) 2024 Microsoft Corporation
+@ * Copyright (c) 2026-present Eclipse ThreadX contributors
@ *
@ * This program and the accompanying materials are made available under the
@ * terms of the MIT License which is available at
@@ -8,6 +9,7 @@
@ * SPDX-License-Identifier: MIT
@ **************************************************************************/
@
+@ Portions of this file were generated with AI assistance.
@
@/**************************************************************************/
@/**************************************************************************/
@@ -71,7 +73,7 @@
_tx_thread_smp_time_get:
MRC p15, 4, r0, c15, c0, 0 @ Read periph base address
- LDR r0, [r0, #0x604] @ Read count register
+ LDR r0, [r0, #0x200] @ Read global timer count low register
#ifdef __THUMB_INTERWORK
BX lr @ Return to caller
@@ -79,4 +81,3 @@ _tx_thread_smp_time_get:
MOV pc, lr @ Return to caller
#endif
-
diff --git a/ports_smp/cortex_a5_smp/gnu/src/tx_thread_smp_unprotect.S b/ports_smp/cortex_a5_smp/gnu/src/tx_thread_smp_unprotect.S
index 4cccae92..e00f53ec 100644
--- a/ports_smp/cortex_a5_smp/gnu/src/tx_thread_smp_unprotect.S
+++ b/ports_smp/cortex_a5_smp/gnu/src/tx_thread_smp_unprotect.S
@@ -1,5 +1,6 @@
@/***************************************************************************
@ * Copyright (c) 2024 Microsoft Corporation
+@ * 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
@@ -7,6 +8,7 @@
@ *
@ * SPDX-License-Identifier: MIT
@ **************************************************************************/
+@ Portions of this file were generated with AI assistance.
@
@
@/**************************************************************************/
@@ -33,7 +35,6 @@
.global _tx_thread_current_ptr
.global _tx_thread_smp_protection
.global _tx_thread_preempt_disable
- .global _tx_thread_smp_protect_wait_counts
.arm
.text
@@ -105,10 +106,6 @@ _tx_thread_smp_unprotect:
CMP r3, #0 @ Is the preempt disable flag set?
BNE _still_protected @ Yes, skip the protection release
- LDR r2,=_tx_thread_smp_protect_wait_counts @ Build build address of wait counts
- LDR r3, [r2, r1, LSL #2] @ Pickup wait list value
- CMP r3, #0 @ Are any entities on this core waiting?
- BNE _still_protected @ Yes, skip the protection release
LDR r2,=_tx_thread_smp_protection @ Build address of protection structure
MOV r3, #0xFFFFFFFF @ Build invalid value
diff --git a/ports_smp/cortex_a5_smp/gnu/src/tx_thread_system_return.S b/ports_smp/cortex_a5_smp/gnu/src/tx_thread_system_return.S
index f49d8324..4451fdd5 100644
--- a/ports_smp/cortex_a5_smp/gnu/src/tx_thread_system_return.S
+++ b/ports_smp/cortex_a5_smp/gnu/src/tx_thread_system_return.S
@@ -1,5 +1,6 @@
@/***************************************************************************
@ * Copyright (c) 2024 Microsoft Corporation
+@ * Copyright (c) 2026-present Eclipse ThreadX contributors
@ *
@ * This program and the accompanying materials are made available under the
@ * terms of the MIT License which is available at
@@ -8,6 +9,7 @@
@ * SPDX-License-Identifier: MIT
@ **************************************************************************/
@
+@ Portions of this file were generated with AI assistance.
@
@/**************************************************************************/
@/**************************************************************************/
@@ -134,9 +136,10 @@ _tx_skip_solicited_vfp_save:
ADD r2, r2, r12 @ Build index into time-slice array
LDR r1, [r2, #0] @ Pickup current time slice
@
-@ /* Save current stack and switch to system stack. */
+@ /* Save the current stack pointer in the thread's control block. The
+@ scheduler runs on this core's banked SVC mode stack, which the startup
+@ code set up, so there is no stack switch to perform. */
@ _tx_thread_current_ptr[core] -> tx_thread_stack_ptr = sp;
-@ sp = _tx_thread_system_stack_ptr[core];
@
STR sp, [r0, #8] @ Save thread stack pointer
@
diff --git a/ports_smp/cortex_a5_smp/gnu/src/tx_thread_vectored_context_save.S b/ports_smp/cortex_a5_smp/gnu/src/tx_thread_vectored_context_save.S
index aed336ad..67711a9c 100644
--- a/ports_smp/cortex_a5_smp/gnu/src/tx_thread_vectored_context_save.S
+++ b/ports_smp/cortex_a5_smp/gnu/src/tx_thread_vectored_context_save.S
@@ -1,5 +1,6 @@
@/***************************************************************************
@ * Copyright (c) 2024 Microsoft Corporation
+@ * Copyright (c) 2026-present Eclipse ThreadX contributors
@ *
@ * This program and the accompanying materials are made available under the
@ * terms of the MIT License which is available at
@@ -8,6 +9,7 @@
@ * SPDX-License-Identifier: MIT
@ **************************************************************************/
@
+@ Portions of this file were generated with AI assistance.
@
@/**************************************************************************/
@/**************************************************************************/
@@ -145,11 +147,11 @@ __tx_thread_not_nested_save:
@
@ /* Note: Minimal context of interrupted thread is already saved. */
@
-@ /* Save the current stack pointer in the thread's control block. */
-@ _tx_thread_current_ptr[core] -> tx_thread_stack_ptr = sp;
-@
-@ /* Switch to the system stack. */
-@ sp = _tx_thread_system_stack_ptr[core];
+@ /* This routine runs in IRQ mode on this core's banked IRQ stack, which
+@ serves as the system stack on this architecture, so there is no stack
+@ switch to perform here. The thread's stack pointer is saved in its
+@ control block by _tx_thread_context_restore, and only when the
+@ interrupt results in preemption. */
@
MOV r10, #0 @ Clear stack limit
diff --git a/ports_smp/cortex_a5x_smp/ac6/example_build/sample_threadx/sample_threadx.launch b/ports_smp/cortex_a5x_smp/ac6/example_build/sample_threadx/sample_threadx.launch
index 1bb76fab..1324b9bd 100644
--- a/ports_smp/cortex_a5x_smp/ac6/example_build/sample_threadx/sample_threadx.launch
+++ b/ports_smp/cortex_a5x_smp/ac6/example_build/sample_threadx/sample_threadx.launch
@@ -210,13 +210,6 @@
<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"/>
@@ -387,17 +380,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_a5x_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-A53x4&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_smp/cortex_a5x_smp/ac6/example_build/sample_threadx/startup_AArch64-FVP_Base_AEMv8A.launch b/ports_smp/cortex_a5x_smp/ac6/example_build/sample_threadx/startup_AArch64-FVP_Base_AEMv8A.launch
index fc1a8ba9..e64d68f8 100644
--- a/ports_smp/cortex_a5x_smp/ac6/example_build/sample_threadx/startup_AArch64-FVP_Base_AEMv8A.launch
+++ b/ports_smp/cortex_a5x_smp/ac6/example_build/sample_threadx/startup_AArch64-FVP_Base_AEMv8A.launch
@@ -207,17 +207,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&gt;&#10;&#9;&lt;breakpoint location_expression=&quot;EL1N:l64_fiq&quot; ignorecount=&quot;0&quot; threadenabled=&quot;no&quot; core_list=&quot;&quot; continue=&quot;no&quot; verboseBreakpoints=&quot;yes&quot; kind=&quot;EXPRESSION&quot;&gt;&#10;&#9;&lt;/breakpoint&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;RAW_EXEC_ADDRESS&quot;&gt;&#10;&#9;&#9;&lt;master_location index=&quot;0&quot; enabled=&quot;true&quot; version=&quot;2&quot; address=&quot;EL1N:0x0000000080000400&quot;/&gt;&#10;&#9;&#9;&lt;location index=&quot;0&quot; enabled=&quot;true&quot; version=&quot;2&quot; address=&quot;EL1N:0x0000000080000400&quot; debugFile=&quot;B:/support/broadcom/tx58cortexa53arm/release/threadx/sample_threadx/vectors.S&quot; line=&quot;79&quot;/&gt;&#10;&#9;&lt;/breakpoint&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;RAW_EXEC_ADDRESS&quot;&gt;&#10;&#9;&#9;&lt;master_location index=&quot;0&quot; enabled=&quot;true&quot; version=&quot;2&quot; address=&quot;EL3:0x0000000080000200&quot; debugFile=&quot;B:/support/broadcom/tx58cortexa53arm/release/threadx/sample_threadx/vectors.S&quot; hostFile=&quot;B:\support\broadcom\tx58cortexa53arm\release\threadx\sample_threadx\vectors.S&quot; line=&quot;61&quot;/&gt;&#10;&#9;&#9;&lt;location index=&quot;0&quot; enabled=&quot;true&quot; version=&quot;2&quot; address=&quot;EL3:0x0000000080000200&quot; debugFile=&quot;B:/support/broadcom/tx58cortexa53arm/release/threadx/sample_threadx/vectors.S&quot; hostFile=&quot;B:\support\broadcom\tx58cortexa53arm\release\threadx\sample_threadx\vectors.S&quot; line=&quot;61&quot;/&gt;&#10;&#9;&lt;/breakpoint&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;RAW_EXEC_ADDRESS&quot;&gt;&#10;&#9;&#9;&lt;master_location index=&quot;0&quot; enabled=&quot;true&quot; version=&quot;2&quot; address=&quot;EL1N:0x00000000800009F8&quot;/&gt;&#10;&#9;&#9;&lt;location index=&quot;0&quot; enabled=&quot;true&quot; version=&quot;2&quot; address=&quot;EL1N:0x00000000800009F8&quot; debugFile=&quot;B:/support/broadcom/tx58cortexa53arm/release/threadx/sample_threadx/entry.S&quot; line=&quot;274&quot;/&gt;&#10;&#9;&lt;/breakpoint&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;RAW_EXEC_ADDRESS&quot;&gt;&#10;&#9;&#9;&lt;master_location index=&quot;0&quot; enabled=&quot;true&quot; version=&quot;2&quot; address=&quot;EL1N:0x0000000080000CCC&quot;/&gt;&#10;&#9;&#9;&lt;location index=&quot;0&quot; enabled=&quot;true&quot; version=&quot;2&quot; address=&quot;EL1N:0x0000000080000CCC&quot; debugFile=&quot;B:/support/broadcom/tx58cortexa53arm/release/threadx/tx/tx_thread_context_save.S&quot; line=&quot;253&quot;/&gt;&#10;&#9;&lt;/breakpoint&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;RAW_EXEC_ADDRESS&quot;&gt;&#10;&#9;&#9;&lt;master_location index=&quot;0&quot; enabled=&quot;true&quot; version=&quot;2&quot; address=&quot;EL1N:0x0000000080000FA0&quot;/&gt;&#10;&#9;&#9;&lt;location index=&quot;0&quot; enabled=&quot;false&quot; version=&quot;2&quot; address=&quot;EL1N:0x0000000080000FA0&quot; debugFile=&quot;B:/support/broadcom/tx58cortexa53arm/release/threadx/tx/tx_thread_schedule.S&quot; line=&quot;244&quot;/&gt;&#10;&#9;&lt;/breakpoint&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;RAW_EXEC_ADDRESS&quot;&gt;&#10;&#9;&#9;&lt;master_location index=&quot;0&quot; enabled=&quot;true&quot; version=&quot;2&quot; address=&quot;EL1N:0x000000008000628C&quot;/&gt;&#10;&#9;&#9;&lt;location index=&quot;0&quot; enabled=&quot;true&quot; version=&quot;2&quot; address=&quot;EL1N:0x000000008000628C&quot; debugFile=&quot;B:/support/broadcom/tx58cortexa53arm/release/threadx/tx/tx_thread_shell_entry.c&quot; line=&quot;254&quot;/&gt;&#10;&#9;&lt;/breakpoint&gt;&#10;&#9;&lt;breakpoint location_expression=&quot;EL2N:0x800009f8&quot; ignorecount=&quot;0&quot; threadenabled=&quot;no&quot; core_list=&quot;&quot; continue=&quot;no&quot; verboseBreakpoints=&quot;yes&quot; kind=&quot;EXPRESSION&quot;&gt;&#10;&#9;&#9;&lt;master_location index=&quot;0&quot; enabled=&quot;true&quot; version=&quot;2&quot; address=&quot;EL2N:0x00000000800009F8&quot;/&gt;&#10;&#9;&#9;&lt;location index=&quot;0&quot; enabled=&quot;false&quot; version=&quot;2&quot; address=&quot;EL2N:0x00000000800009F8&quot;/&gt;&#10;&#9;&lt;/breakpoint&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;RAW_EXEC_ADDRESS&quot;&gt;&#10;&#9;&#9;&lt;master_location index=&quot;0&quot; enabled=&quot;true&quot; version=&quot;2&quot; address=&quot;EL1N:0x000000008000BF88&quot;/&gt;&#10;&#9;&#9;&lt;location index=&quot;0&quot; enabled=&quot;false&quot; version=&quot;2&quot; address=&quot;EL1N:0x000000008000BF88&quot; debugFile=&quot;B:/support/broadcom/tx58cortexa53arm/release/threadx/sample_threadx/sample_threadx.c&quot; line=&quot;239&quot;/&gt;&#10;&#9;&lt;/breakpoint&gt;&#10;&#9;&lt;breakpoint location_expression=&quot;EL1N:0x0000000080000D84&quot; ignorecount=&quot;0&quot; threadenabled=&quot;no&quot; core_list=&quot;&quot; continue=&quot;no&quot; verboseBreakpoints=&quot;yes&quot; kind=&quot;EXPRESSION&quot;&gt;&#10;&#9;&#9;&lt;master_location index=&quot;0&quot; enabled=&quot;true&quot; version=&quot;2&quot; address=&quot;EL1N:0x0000000080000D84&quot;/&gt;&#10;&#9;&#9;&lt;location index=&quot;0&quot; enabled=&quot;true&quot; version=&quot;2&quot; address=&quot;EL1N:0x0000000080000D84&quot; debugFile=&quot;B:/support/broadcom/tx58cortexa53arm/release/threadx/tx/tx_timer_interrupt.S&quot; line=&quot;128&quot;/&gt;&#10;&#9;&lt;/breakpoint&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;RAW_EXEC_ADDRESS&quot;&gt;&#10;&#9;&#9;&lt;master_location index=&quot;0&quot; enabled=&quot;false&quot; version=&quot;2&quot; address=&quot;EL1N:0x0000000080000F40&quot;/&gt;&#10;&#9;&#9;&lt;location index=&quot;0&quot; enabled=&quot;false&quot; version=&quot;2&quot; address=&quot;EL1N:0x0000000080000F40&quot; debugFile=&quot;B:/support/broadcom/tx58cortexa53arm/release/threadx/tx/tx_thread_schedule.S&quot; line=&quot;164&quot;/&gt;&#10;&#9;&lt;/breakpoint&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;RAW_EXEC_ADDRESS&quot;&gt;&#10;&#9;&#9;&lt;master_location index=&quot;0&quot; enabled=&quot;true&quot; version=&quot;2&quot; address=&quot;EL1N:0x000000008000BFC8&quot;/&gt;&#10;&#9;&#9;&lt;location index=&quot;0&quot; enabled=&quot;true&quot; version=&quot;2&quot; address=&quot;EL1N:0x000000008000BFC8&quot; debugFile=&quot;B:/support/broadcom/tx58cortexa53arm/release/threadx/sample_threadx/sample_threadx.c&quot; hostFile=&quot;B:\support\broadcom\tx58cortexa53arm\release\threadx\sample_threadx\sample_threadx.c&quot; line=&quot;251&quot;/&gt;&#10;&#9;&lt;/breakpoint&gt;&#10;&#9;&lt;breakpoint location_expression=&quot;EL1N:0x80000200&quot; ignorecount=&quot;0&quot; threadenabled=&quot;no&quot; core_list=&quot;&quot; continue=&quot;no&quot; verboseBreakpoints=&quot;yes&quot; kind=&quot;EXPRESSION&quot;&gt;&#10;&#9;&#9;&lt;master_location index=&quot;0&quot; enabled=&quot;true&quot; version=&quot;2&quot; address=&quot;EL1N:0x0000000080000200&quot;/&gt;&#10;&#9;&#9;&lt;location index=&quot;0&quot; enabled=&quot;true&quot; version=&quot;2&quot; address=&quot;EL1N:0x0000000080000200&quot; debugFile=&quot;B:/support/broadcom/tx58cortexa53arm/release/threadx/sample_threadx/vectors.S&quot; hostFile=&quot;B:\support\broadcom\tx58cortexa53arm\release\threadx\sample_threadx\vectors.S&quot; line=&quot;61&quot;/&gt;&#10;&#9;&lt;/breakpoint&gt;&#10;&#9;&lt;breakpoint location_expression=&quot;EL3:0x0000000080000D84&quot; ignorecount=&quot;0&quot; threadenabled=&quot;no&quot; core_list=&quot;&quot; continue=&quot;no&quot; verboseBreakpoints=&quot;yes&quot; kind=&quot;EXPRESSION&quot;&gt;&#10;&#9;&#9;&lt;master_location index=&quot;0&quot; enabled=&quot;false&quot; version=&quot;2&quot; address=&quot;EL3:0x0000000080000D84&quot; debugFile=&quot;B:/support/broadcom/tx58cortexa53arm/release/threadx/tx/tx_timer_interrupt.S&quot; hostFile=&quot;B:\support\broadcom\tx58cortexa53arm\release\threadx\tx\tx_timer_interrupt.S&quot; line=&quot;128&quot;/&gt;&#10;&#9;&#9;&lt;location index=&quot;0&quot; enabled=&quot;true&quot; version=&quot;2&quot; address=&quot;EL3:0x0000000080000D84&quot; debugFile=&quot;B:/support/broadcom/tx58cortexa53arm/release/threadx/tx/tx_timer_interrupt.S&quot; hostFile=&quot;B:\support\broadcom\tx58cortexa53arm\release\threadx\tx\tx_timer_interrupt.S&quot; line=&quot;128&quot;/&gt;&#10;&#9;&lt;/breakpoint&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;RAW_EXEC_ADDRESS&quot;&gt;&#10;&#9;&#9;&lt;master_location index=&quot;0&quot; enabled=&quot;true&quot; version=&quot;2&quot; address=&quot;EL1N:0x0000000080000000&quot;/&gt;&#10;&#9;&#9;&lt;location index=&quot;0&quot; enabled=&quot;true&quot; version=&quot;2&quot; address=&quot;EL1N:0x0000000080000000&quot; debugFile=&quot;B:/support/broadcom/tx58cortexa53arm/release/threadx/sample_threadx/vectors.S&quot; hostFile=&quot;B:\support\broadcom\tx58cortexa53arm\release\threadx\sample_threadx\vectors.S&quot; line=&quot;38&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&gt;&#10;&lt;/breakpoints&gt;&#10;"/>
<listAttribute key="com.arm.debug.views.common.AddressTracker.debugger.view.DisassemblyView.addresses">
<listEntry value="$pc"/>
<listEntry value=""/>
@@ -388,14 +381,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\tx58cortexa53arm\release\threadx\sample_threadx\use_model_semihosting.ds" value=""/>
-</mapAttribute>
<listAttribute key="setup">
<listEntry value="DS5://sw/debugger/configdb/Scripts/rtsm_launcher.py"/>
<listEntry value="DS5://bin/FVP_Base_AEMv8A"/>
</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_smp/cortex_a5x_smp/ac6/inc/tx_port.h b/ports_smp/cortex_a5x_smp/ac6/inc/tx_port.h
index 2000b6f5..14b1f783 100644
--- a/ports_smp/cortex_a5x_smp/ac6/inc/tx_port.h
+++ b/ports_smp/cortex_a5x_smp/ac6/inc/tx_port.h
@@ -412,7 +412,7 @@ VOID tx_thread_fp_disable(VOID);
#ifdef TX_THREAD_INIT
CHAR _tx_version_id[] =
- "Copyright (c) 1996-2019 Express Logic Inc. * ThreadX Cortex-A5x-SMP/AC6 Version 6.5.1.202602a *";
+ "Copyright (c) 1996-2019 Express Logic Inc. * ThreadX Cortex-A5x-SMP/AC6 Version 6.5.2.202603 *";
#else
extern CHAR _tx_version_id[];
#endif
diff --git a/ports_smp/cortex_a5x_smp/ac6/src/tx_thread_smp_time_get.S b/ports_smp/cortex_a5x_smp/ac6/src/tx_thread_smp_time_get.S
index efa6d62c..7a20db32 100644
--- a/ports_smp/cortex_a5x_smp/ac6/src/tx_thread_smp_time_get.S
+++ b/ports_smp/cortex_a5x_smp/ac6/src/tx_thread_smp_time_get.S
@@ -9,6 +9,7 @@
* SPDX-License-Identifier: MIT
**************************************************************************/
+// Portions of this file were generated with AI assistance.
/**************************************************************************/
/**************************************************************************/
@@ -58,5 +59,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_smp/cortex_a5x_smp/gnu/CMakeLists.txt b/ports_smp/cortex_a5x_smp/gnu/CMakeLists.txt
new file mode 100644
index 00000000..08db4117
--- /dev/null
+++ b/ports_smp/cortex_a5x_smp/gnu/CMakeLists.txt
@@ -0,0 +1,38 @@
+# Copyright (c) 2026 Eclipse ThreadX contributors
+# SPDX-License-Identifier: MIT
+# Portions of this file were generated with AI assistance.
+#
+# ThreadX port sources for cortex_a5x_smp, GNU tools.
+
+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_smp/cortex_a5x_smp/gnu/example_build/sample_threadx/sample_threadx.launch b/ports_smp/cortex_a5x_smp/gnu/example_build/sample_threadx/sample_threadx.launch
index 2718a398..d5d36204 100644
--- a/ports_smp/cortex_a5x_smp/gnu/example_build/sample_threadx/sample_threadx.launch
+++ b/ports_smp/cortex_a5x_smp/gnu/example_build/sample_threadx/sample_threadx.launch
@@ -233,13 +233,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"/>
@@ -414,21 +407,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_a5x_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-A53x4&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_smp/cortex_a5x_smp/gnu/inc/tx_port.h b/ports_smp/cortex_a5x_smp/gnu/inc/tx_port.h
index 90e2da85..25494438 100644
--- a/ports_smp/cortex_a5x_smp/gnu/inc/tx_port.h
+++ b/ports_smp/cortex_a5x_smp/gnu/inc/tx_port.h
@@ -412,7 +412,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 Cortex-A5x-SMP/GNU Version 6.5.1.202602a *";
+ "(c) 2024 Microsoft Corp. (c) 2026-present Eclipse ThreadX contributors. * ThreadX Cortex-A5x-SMP/GNU Version 6.5.2.202603 *";
#else
extern CHAR _tx_version_id[];
#endif
diff --git a/ports_smp/cortex_a5x_smp/gnu/src/tx_thread_smp_time_get.S b/ports_smp/cortex_a5x_smp/gnu/src/tx_thread_smp_time_get.S
index 4a98140a..4b3ee1d4 100644
--- a/ports_smp/cortex_a5x_smp/gnu/src/tx_thread_smp_time_get.S
+++ b/ports_smp/cortex_a5x_smp/gnu/src/tx_thread_smp_time_get.S
@@ -9,6 +9,7 @@
* SPDX-License-Identifier: MIT
**************************************************************************/
+// Portions of this file were generated with AI assistance.
/**************************************************************************/
/**************************************************************************/
@@ -58,5 +59,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_smp/cortex_a5x_smp/green/inc/tx_port.h b/ports_smp/cortex_a5x_smp/green/inc/tx_port.h
index 50476b1c..bae66fef 100644
--- a/ports_smp/cortex_a5x_smp/green/inc/tx_port.h
+++ b/ports_smp/cortex_a5x_smp/green/inc/tx_port.h
@@ -432,7 +432,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 Cortex-A5x-SMP/GHS Version 6.5.1.202602a *";
+ "(c) 2024 Microsoft Corp. (c) 2026-present Eclipse ThreadX contributors. * ThreadX Cortex-A5x-SMP/GHS Version 6.5.2.202603 *";
#else
extern CHAR _tx_version_id[];
#endif
diff --git a/ports_smp/cortex_a5x_smp/green/src/tx_thread_smp_time_get.a64 b/ports_smp/cortex_a5x_smp/green/src/tx_thread_smp_time_get.a64
index 45d286b0..37514c26 100644
--- a/ports_smp/cortex_a5x_smp/green/src/tx_thread_smp_time_get.a64
+++ b/ports_smp/cortex_a5x_smp/green/src/tx_thread_smp_time_get.a64
@@ -1,5 +1,6 @@
/***************************************************************************
* Copyright (c) 2024 Microsoft Corporation
+ * Copyright (c) 2026-present Eclipse ThreadX contributors
*
* This program and the accompanying materials are made available under the
* terms of the MIT License which is available at
@@ -8,6 +9,7 @@
* SPDX-License-Identifier: MIT
**************************************************************************/
+// Portions of this file were generated with AI assistance.
/**************************************************************************/
/**************************************************************************/
@@ -76,7 +78,7 @@
.global _tx_thread_smp_time_get
.type _tx_thread_smp_time_get, @function
_tx_thread_smp_time_get:
- MOV x0, #0 // Add time source - application specific
+ MRS x0, CNTPCT_EL0 // Read generic timer physical count
RET
diff --git a/ports_smp/cortex_a5x_smp/iar/inc/tx_port.h b/ports_smp/cortex_a5x_smp/iar/inc/tx_port.h
index 0bd49528..29003aee 100644
--- a/ports_smp/cortex_a5x_smp/iar/inc/tx_port.h
+++ b/ports_smp/cortex_a5x_smp/iar/inc/tx_port.h
@@ -441,7 +441,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 Cortex-A5x-SMP/IAR Version 6.5.1.202602a *";
+ "(c) 2024 Microsoft Corp. (c) 2026-present Eclipse ThreadX contributors. * ThreadX Cortex-A5x-SMP/IAR Version 6.5.2.202603 *";
#else
extern CHAR _tx_version_id[];
#endif
diff --git a/ports_smp/cortex_a5x_smp/iar/src/tx_thread_smp_time_get.S b/ports_smp/cortex_a5x_smp/iar/src/tx_thread_smp_time_get.S
index 43834196..16cdf26d 100644
--- a/ports_smp/cortex_a5x_smp/iar/src/tx_thread_smp_time_get.S
+++ b/ports_smp/cortex_a5x_smp/iar/src/tx_thread_smp_time_get.S
@@ -9,6 +9,7 @@
* SPDX-License-Identifier: MIT
**************************************************************************/
+// Portions of this file were generated with AI assistance.
/**************************************************************************/
/**************************************************************************/
@@ -70,7 +71,7 @@
/**************************************************************************/
PUBLIC _tx_thread_smp_time_get
_tx_thread_smp_time_get:
- MOV x0, #0 // Add logic to get timer value here for diagnostics
+ MRS x0, CNTPCT_EL0 // Read generic timer physical count
RET
END
diff --git a/ports_smp/cortex_a65_smp/ac6/example_build/sample_threadx/sample_threadx.launch b/ports_smp/cortex_a65_smp/ac6/example_build/sample_threadx/sample_threadx.launch
index 35b90705..40148e64 100644
--- a/ports_smp/cortex_a65_smp/ac6/example_build/sample_threadx/sample_threadx.launch
+++ b/ports_smp/cortex_a65_smp/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;"/>
@@ -316,13 +309,13 @@
<listAttribute key="com.arm.debugger.views.common.AddressTracker.debugger.view.DisassemblyView.ranges">
<listEntry value="100"/>
</listAttribute>
- <stringAttribute key="config_db_activity_name" value="Cortex-A35x4 SMP"/>
+ <stringAttribute key="config_db_activity_name" value="Cortex-A65x4 SMP"/>
<stringAttribute key="config_db_connection_keys" value="dtsl_config dtsl_tracecapture_option connect_existing_model dtsl_config_script model_params model_iris config_file model_connection_address setup TCP_KILL_ON_EXIT TCP_DISABLE_EXTENDED_MODE"/>
<stringAttribute key="config_db_connection_type" value="Bare Metal Debug"/>
<stringAttribute key="config_db_platform_name" value="Arm FVP - Base_A65x4"/>
<stringAttribute key="config_db_project_type" value="Bare Metal Debug"/>
<stringAttribute key="config_db_project_type_id" value="BARE_METAL"/>
- <stringAttribute key="config_db_taxonomy_id" value="/platform/armfvp/base_a35x4"/>
+ <stringAttribute key="config_db_taxonomy_id" value="/platform/armfvp/base_a65x4"/>
<stringAttribute key="config_file" value="CDB://iris_config.xml"/>
<booleanAttribute key="connectOnly" value="false"/>
<stringAttribute key="connect_existing_model" value="false"/>
@@ -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-A65x4&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_smp/cortex_a65_smp/ac6/inc/tx_port.h b/ports_smp/cortex_a65_smp/ac6/inc/tx_port.h
index e97d78d5..38c86cb2 100644
--- a/ports_smp/cortex_a65_smp/ac6/inc/tx_port.h
+++ b/ports_smp/cortex_a65_smp/ac6/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_smp/cortex_a65_smp/ac6/src/tx_thread_smp_time_get.S b/ports_smp/cortex_a65_smp/ac6/src/tx_thread_smp_time_get.S
index 335824fb..4bb9f1cb 100644
--- a/ports_smp/cortex_a65_smp/ac6/src/tx_thread_smp_time_get.S
+++ b/ports_smp/cortex_a65_smp/ac6/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_smp/cortex_a65_smp/gnu/CMakeLists.txt b/ports_smp/cortex_a65_smp/gnu/CMakeLists.txt
new file mode 100644
index 00000000..36f7492b
--- /dev/null
+++ b/ports_smp/cortex_a65_smp/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_smp/cortex_a65_smp/gnu/example_build/build_threadx.sh b/ports_smp/cortex_a65_smp/gnu/example_build/build_threadx.sh
new file mode 100755
index 00000000..b3b2cd36
--- /dev/null
+++ b/ports_smp/cortex_a65_smp/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_smp/cortex_a65_smp/gnu/example_build/build_threadx_sample.sh b/ports_smp/cortex_a65_smp/gnu/example_build/build_threadx_sample.sh
new file mode 100755
index 00000000..94248a88
--- /dev/null
+++ b/ports_smp/cortex_a65_smp/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_smp/cortex_a65_smp/gnu/example_build/readme.md b/ports_smp/cortex_a65_smp/gnu/example_build/readme.md
new file mode 100644
index 00000000..3c52a7da
--- /dev/null
+++ b/ports_smp/cortex_a65_smp/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_smp/cortex_a65_smp/gnu/example_build/sample_threadx/sample_threadx.launch b/ports_smp/cortex_a65_smp/gnu/example_build/sample_threadx/sample_threadx.launch
index bc7dcad0..936fbc87 100644
--- a/ports_smp/cortex_a65_smp/gnu/example_build/sample_threadx/sample_threadx.launch
+++ b/ports_smp/cortex_a65_smp/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"/>
@@ -345,13 +338,13 @@
<listAttribute key="com.arm.debugger.views.common.AddressTracker.debugger.view.DisassemblyView.ranges">
<listEntry value="100"/>
</listAttribute>
- <stringAttribute key="config_db_activity_name" value="Cortex-A35x4 SMP"/>
+ <stringAttribute key="config_db_activity_name" value="Cortex-A65x4 SMP"/>
<stringAttribute key="config_db_connection_keys" value="dtsl_config dtsl_tracecapture_option connect_existing_model dtsl_config_script model_params model_iris config_file model_connection_address setup TCP_KILL_ON_EXIT TCP_DISABLE_EXTENDED_MODE"/>
<stringAttribute key="config_db_connection_type" value="Bare Metal Debug"/>
<stringAttribute key="config_db_platform_name" value="Arm FVP - Base_A65x4"/>
<stringAttribute key="config_db_project_type" value="Bare Metal Debug"/>
<stringAttribute key="config_db_project_type_id" value="BARE_METAL"/>
- <stringAttribute key="config_db_taxonomy_id" value="/platform/armfvp/base_a35x4"/>
+ <stringAttribute key="config_db_taxonomy_id" value="/platform/armfvp/base_a65x4"/>
<stringAttribute key="config_file" value="CDB://iris_config.xml"/>
<booleanAttribute key="connectOnly" value="false"/>
<stringAttribute key="connect_existing_model" value="false"/>
@@ -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-A65x4&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_smp/cortex_a65_smp/gnu/example_build/sample_threadx/semihost_stub.S b/ports_smp/cortex_a65_smp/gnu/example_build/sample_threadx/semihost_stub.S
new file mode 100644
index 00000000..c456875d
--- /dev/null
+++ b/ports_smp/cortex_a65_smp/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_smp/cortex_a65_smp/gnu/inc/tx_port.h b/ports_smp/cortex_a65_smp/gnu/inc/tx_port.h
index e97d78d5..38c86cb2 100644
--- a/ports_smp/cortex_a65_smp/gnu/inc/tx_port.h
+++ b/ports_smp/cortex_a65_smp/gnu/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_smp/cortex_a65_smp/gnu/src/tx_thread_smp_time_get.S b/ports_smp/cortex_a65_smp/gnu/src/tx_thread_smp_time_get.S
index 335824fb..4bb9f1cb 100644
--- a/ports_smp/cortex_a65_smp/gnu/src/tx_thread_smp_time_get.S
+++ b/ports_smp/cortex_a65_smp/gnu/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_smp/cortex_a65ae_smp/ac6/example_build/sample_threadx/sample_threadx.launch b/ports_smp/cortex_a65ae_smp/ac6/example_build/sample_threadx/sample_threadx.launch
index 09d5f09b..7075858b 100644
--- a/ports_smp/cortex_a65ae_smp/ac6/example_build/sample_threadx/sample_threadx.launch
+++ b/ports_smp/cortex_a65ae_smp/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;"/>
@@ -316,13 +309,13 @@
<listAttribute key="com.arm.debugger.views.common.AddressTracker.debugger.view.DisassemblyView.ranges">
<listEntry value="100"/>
</listAttribute>
- <stringAttribute key="config_db_activity_name" value="Cortex-A35x4 SMP"/>
+ <stringAttribute key="config_db_activity_name" value="Cortex-A65AEx4 SMP"/>
<stringAttribute key="config_db_connection_keys" value="dtsl_config dtsl_tracecapture_option connect_existing_model dtsl_config_script model_params model_iris config_file model_connection_address setup TCP_KILL_ON_EXIT TCP_DISABLE_EXTENDED_MODE"/>
<stringAttribute key="config_db_connection_type" value="Bare Metal Debug"/>
<stringAttribute key="config_db_platform_name" value="Arm FVP - Base_A65AEx4"/>
<stringAttribute key="config_db_project_type" value="Bare Metal Debug"/>
<stringAttribute key="config_db_project_type_id" value="BARE_METAL"/>
- <stringAttribute key="config_db_taxonomy_id" value="/platform/armfvp/base_a35x4"/>
+ <stringAttribute key="config_db_taxonomy_id" value="/platform/armfvp/base_a65aex4"/>
<stringAttribute key="config_file" value="CDB://iris_config.xml"/>
<booleanAttribute key="connectOnly" value="false"/>
<stringAttribute key="connect_existing_model" value="false"/>
@@ -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-A65AEx4&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_smp/cortex_a65ae_smp/ac6/inc/tx_port.h b/ports_smp/cortex_a65ae_smp/ac6/inc/tx_port.h
index e97d78d5..38c86cb2 100644
--- a/ports_smp/cortex_a65ae_smp/ac6/inc/tx_port.h
+++ b/ports_smp/cortex_a65ae_smp/ac6/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_smp/cortex_a65ae_smp/ac6/src/tx_thread_smp_time_get.S b/ports_smp/cortex_a65ae_smp/ac6/src/tx_thread_smp_time_get.S
index 335824fb..4bb9f1cb 100644
--- a/ports_smp/cortex_a65ae_smp/ac6/src/tx_thread_smp_time_get.S
+++ b/ports_smp/cortex_a65ae_smp/ac6/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_smp/cortex_a65ae_smp/gnu/CMakeLists.txt b/ports_smp/cortex_a65ae_smp/gnu/CMakeLists.txt
new file mode 100644
index 00000000..36f7492b
--- /dev/null
+++ b/ports_smp/cortex_a65ae_smp/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_smp/cortex_a65ae_smp/gnu/example_build/build_threadx.sh b/ports_smp/cortex_a65ae_smp/gnu/example_build/build_threadx.sh
new file mode 100755
index 00000000..b3b2cd36
--- /dev/null
+++ b/ports_smp/cortex_a65ae_smp/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_smp/cortex_a65ae_smp/gnu/example_build/build_threadx_sample.sh b/ports_smp/cortex_a65ae_smp/gnu/example_build/build_threadx_sample.sh
new file mode 100755
index 00000000..94248a88
--- /dev/null
+++ b/ports_smp/cortex_a65ae_smp/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_smp/cortex_a65ae_smp/gnu/example_build/readme.md b/ports_smp/cortex_a65ae_smp/gnu/example_build/readme.md
new file mode 100644
index 00000000..3c52a7da
--- /dev/null
+++ b/ports_smp/cortex_a65ae_smp/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_smp/cortex_a65ae_smp/gnu/example_build/sample_threadx/sample_threadx.launch b/ports_smp/cortex_a65ae_smp/gnu/example_build/sample_threadx/sample_threadx.launch
index 0ffed216..6fbaed29 100644
--- a/ports_smp/cortex_a65ae_smp/gnu/example_build/sample_threadx/sample_threadx.launch
+++ b/ports_smp/cortex_a65ae_smp/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"/>
@@ -345,13 +338,13 @@
<listAttribute key="com.arm.debugger.views.common.AddressTracker.debugger.view.DisassemblyView.ranges">
<listEntry value="100"/>
</listAttribute>
- <stringAttribute key="config_db_activity_name" value="Cortex-A35x4 SMP"/>
+ <stringAttribute key="config_db_activity_name" value="Cortex-A65AEx4 SMP"/>
<stringAttribute key="config_db_connection_keys" value="dtsl_config dtsl_tracecapture_option connect_existing_model dtsl_config_script model_params model_iris config_file model_connection_address setup TCP_KILL_ON_EXIT TCP_DISABLE_EXTENDED_MODE"/>
<stringAttribute key="config_db_connection_type" value="Bare Metal Debug"/>
<stringAttribute key="config_db_platform_name" value="Arm FVP - Base_A65AEx4"/>
<stringAttribute key="config_db_project_type" value="Bare Metal Debug"/>
<stringAttribute key="config_db_project_type_id" value="BARE_METAL"/>
- <stringAttribute key="config_db_taxonomy_id" value="/platform/armfvp/base_a35x4"/>
+ <stringAttribute key="config_db_taxonomy_id" value="/platform/armfvp/base_a65aex4"/>
<stringAttribute key="config_file" value="CDB://iris_config.xml"/>
<booleanAttribute key="connectOnly" value="false"/>
<stringAttribute key="connect_existing_model" value="false"/>
@@ -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-A65AEx4&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_smp/cortex_a65ae_smp/gnu/example_build/sample_threadx/semihost_stub.S b/ports_smp/cortex_a65ae_smp/gnu/example_build/sample_threadx/semihost_stub.S
new file mode 100644
index 00000000..c456875d
--- /dev/null
+++ b/ports_smp/cortex_a65ae_smp/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_smp/cortex_a65ae_smp/gnu/inc/tx_port.h b/ports_smp/cortex_a65ae_smp/gnu/inc/tx_port.h
index e97d78d5..38c86cb2 100644
--- a/ports_smp/cortex_a65ae_smp/gnu/inc/tx_port.h
+++ b/ports_smp/cortex_a65ae_smp/gnu/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_smp/cortex_a65ae_smp/gnu/src/tx_thread_smp_time_get.S b/ports_smp/cortex_a65ae_smp/gnu/src/tx_thread_smp_time_get.S
index 335824fb..4bb9f1cb 100644
--- a/ports_smp/cortex_a65ae_smp/gnu/src/tx_thread_smp_time_get.S
+++ b/ports_smp/cortex_a65ae_smp/gnu/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_smp/cortex_a72_smp/ac6/example_build/sample_threadx/sample_threadx.launch b/ports_smp/cortex_a72_smp/ac6/example_build/sample_threadx/sample_threadx.launch
index 354f9ea7..6e400036 100644
--- a/ports_smp/cortex_a72_smp/ac6/example_build/sample_threadx/sample_threadx.launch
+++ b/ports_smp/cortex_a72_smp/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;"/>
@@ -316,13 +309,13 @@
<listAttribute key="com.arm.debugger.views.common.AddressTracker.debugger.view.DisassemblyView.ranges">
<listEntry value="100"/>
</listAttribute>
- <stringAttribute key="config_db_activity_name" value="Cortex-A35x4 SMP"/>
+ <stringAttribute key="config_db_activity_name" value="Cortex-A72x4 SMP"/>
<stringAttribute key="config_db_connection_keys" value="dtsl_config dtsl_tracecapture_option connect_existing_model dtsl_config_script model_params model_iris config_file model_connection_address setup TCP_KILL_ON_EXIT TCP_DISABLE_EXTENDED_MODE"/>
<stringAttribute key="config_db_connection_type" value="Bare Metal Debug"/>
<stringAttribute key="config_db_platform_name" value="Arm FVP - Base_A72x4"/>
<stringAttribute key="config_db_project_type" value="Bare Metal Debug"/>
<stringAttribute key="config_db_project_type_id" value="BARE_METAL"/>
- <stringAttribute key="config_db_taxonomy_id" value="/platform/armfvp/base_a35x4"/>
+ <stringAttribute key="config_db_taxonomy_id" value="/platform/armfvp/base_a72x4"/>
<stringAttribute key="config_file" value="CDB://iris_config.xml"/>
<booleanAttribute key="connectOnly" value="false"/>
<stringAttribute key="connect_existing_model" value="false"/>
@@ -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-A72x4&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_smp/cortex_a72_smp/ac6/inc/tx_port.h b/ports_smp/cortex_a72_smp/ac6/inc/tx_port.h
index e97d78d5..38c86cb2 100644
--- a/ports_smp/cortex_a72_smp/ac6/inc/tx_port.h
+++ b/ports_smp/cortex_a72_smp/ac6/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_smp/cortex_a72_smp/ac6/src/tx_thread_smp_time_get.S b/ports_smp/cortex_a72_smp/ac6/src/tx_thread_smp_time_get.S
index 335824fb..4bb9f1cb 100644
--- a/ports_smp/cortex_a72_smp/ac6/src/tx_thread_smp_time_get.S
+++ b/ports_smp/cortex_a72_smp/ac6/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_smp/cortex_a72_smp/gnu/CMakeLists.txt b/ports_smp/cortex_a72_smp/gnu/CMakeLists.txt
new file mode 100644
index 00000000..36f7492b
--- /dev/null
+++ b/ports_smp/cortex_a72_smp/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_smp/cortex_a72_smp/gnu/example_build/build_threadx.sh b/ports_smp/cortex_a72_smp/gnu/example_build/build_threadx.sh
new file mode 100755
index 00000000..b3b2cd36
--- /dev/null
+++ b/ports_smp/cortex_a72_smp/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_smp/cortex_a72_smp/gnu/example_build/build_threadx_sample.sh b/ports_smp/cortex_a72_smp/gnu/example_build/build_threadx_sample.sh
new file mode 100755
index 00000000..94248a88
--- /dev/null
+++ b/ports_smp/cortex_a72_smp/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_smp/cortex_a72_smp/gnu/example_build/readme.md b/ports_smp/cortex_a72_smp/gnu/example_build/readme.md
new file mode 100644
index 00000000..3c52a7da
--- /dev/null
+++ b/ports_smp/cortex_a72_smp/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_smp/cortex_a72_smp/gnu/example_build/sample_threadx/sample_threadx.launch b/ports_smp/cortex_a72_smp/gnu/example_build/sample_threadx/sample_threadx.launch
index 6a746fbc..0e0032ae 100644
--- a/ports_smp/cortex_a72_smp/gnu/example_build/sample_threadx/sample_threadx.launch
+++ b/ports_smp/cortex_a72_smp/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"/>
@@ -345,13 +338,13 @@
<listAttribute key="com.arm.debugger.views.common.AddressTracker.debugger.view.DisassemblyView.ranges">
<listEntry value="100"/>
</listAttribute>
- <stringAttribute key="config_db_activity_name" value="Cortex-A35x4 SMP"/>
+ <stringAttribute key="config_db_activity_name" value="Cortex-A72x4 SMP"/>
<stringAttribute key="config_db_connection_keys" value="dtsl_config dtsl_tracecapture_option connect_existing_model dtsl_config_script model_params model_iris config_file model_connection_address setup TCP_KILL_ON_EXIT TCP_DISABLE_EXTENDED_MODE"/>
<stringAttribute key="config_db_connection_type" value="Bare Metal Debug"/>
<stringAttribute key="config_db_platform_name" value="Arm FVP - Base_A72x4"/>
<stringAttribute key="config_db_project_type" value="Bare Metal Debug"/>
<stringAttribute key="config_db_project_type_id" value="BARE_METAL"/>
- <stringAttribute key="config_db_taxonomy_id" value="/platform/armfvp/base_a35x4"/>
+ <stringAttribute key="config_db_taxonomy_id" value="/platform/armfvp/base_a72x4"/>
<stringAttribute key="config_file" value="CDB://iris_config.xml"/>
<booleanAttribute key="connectOnly" value="false"/>
<stringAttribute key="connect_existing_model" value="false"/>
@@ -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-A72x4&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_smp/cortex_a72_smp/gnu/example_build/sample_threadx/semihost_stub.S b/ports_smp/cortex_a72_smp/gnu/example_build/sample_threadx/semihost_stub.S
new file mode 100644
index 00000000..c456875d
--- /dev/null
+++ b/ports_smp/cortex_a72_smp/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_smp/cortex_a72_smp/gnu/inc/tx_port.h b/ports_smp/cortex_a72_smp/gnu/inc/tx_port.h
index e97d78d5..38c86cb2 100644
--- a/ports_smp/cortex_a72_smp/gnu/inc/tx_port.h
+++ b/ports_smp/cortex_a72_smp/gnu/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_smp/cortex_a72_smp/gnu/src/tx_thread_smp_time_get.S b/ports_smp/cortex_a72_smp/gnu/src/tx_thread_smp_time_get.S
index 335824fb..4bb9f1cb 100644
--- a/ports_smp/cortex_a72_smp/gnu/src/tx_thread_smp_time_get.S
+++ b/ports_smp/cortex_a72_smp/gnu/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_smp/cortex_a73_smp/ac6/example_build/sample_threadx/sample_threadx.launch b/ports_smp/cortex_a73_smp/ac6/example_build/sample_threadx/sample_threadx.launch
index d9e3d93f..01e2095c 100644
--- a/ports_smp/cortex_a73_smp/ac6/example_build/sample_threadx/sample_threadx.launch
+++ b/ports_smp/cortex_a73_smp/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;"/>
@@ -316,13 +309,13 @@
<listAttribute key="com.arm.debugger.views.common.AddressTracker.debugger.view.DisassemblyView.ranges">
<listEntry value="100"/>
</listAttribute>
- <stringAttribute key="config_db_activity_name" value="Cortex-A35x4 SMP"/>
+ <stringAttribute key="config_db_activity_name" value="Cortex-A73x4 SMP"/>
<stringAttribute key="config_db_connection_keys" value="dtsl_config dtsl_tracecapture_option connect_existing_model dtsl_config_script model_params model_iris config_file model_connection_address setup TCP_KILL_ON_EXIT TCP_DISABLE_EXTENDED_MODE"/>
<stringAttribute key="config_db_connection_type" value="Bare Metal Debug"/>
<stringAttribute key="config_db_platform_name" value="Arm FVP - Base_A73x4"/>
<stringAttribute key="config_db_project_type" value="Bare Metal Debug"/>
<stringAttribute key="config_db_project_type_id" value="BARE_METAL"/>
- <stringAttribute key="config_db_taxonomy_id" value="/platform/armfvp/base_a35x4"/>
+ <stringAttribute key="config_db_taxonomy_id" value="/platform/armfvp/base_a73x4"/>
<stringAttribute key="config_file" value="CDB://iris_config.xml"/>
<booleanAttribute key="connectOnly" value="false"/>
<stringAttribute key="connect_existing_model" value="false"/>
@@ -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-A73x4&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_smp/cortex_a73_smp/ac6/inc/tx_port.h b/ports_smp/cortex_a73_smp/ac6/inc/tx_port.h
index e97d78d5..38c86cb2 100644
--- a/ports_smp/cortex_a73_smp/ac6/inc/tx_port.h
+++ b/ports_smp/cortex_a73_smp/ac6/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_smp/cortex_a73_smp/ac6/src/tx_thread_smp_time_get.S b/ports_smp/cortex_a73_smp/ac6/src/tx_thread_smp_time_get.S
index 335824fb..4bb9f1cb 100644
--- a/ports_smp/cortex_a73_smp/ac6/src/tx_thread_smp_time_get.S
+++ b/ports_smp/cortex_a73_smp/ac6/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_smp/cortex_a73_smp/gnu/CMakeLists.txt b/ports_smp/cortex_a73_smp/gnu/CMakeLists.txt
new file mode 100644
index 00000000..36f7492b
--- /dev/null
+++ b/ports_smp/cortex_a73_smp/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_smp/cortex_a73_smp/gnu/example_build/build_threadx.sh b/ports_smp/cortex_a73_smp/gnu/example_build/build_threadx.sh
new file mode 100755
index 00000000..b3b2cd36
--- /dev/null
+++ b/ports_smp/cortex_a73_smp/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_smp/cortex_a73_smp/gnu/example_build/build_threadx_sample.sh b/ports_smp/cortex_a73_smp/gnu/example_build/build_threadx_sample.sh
new file mode 100755
index 00000000..94248a88
--- /dev/null
+++ b/ports_smp/cortex_a73_smp/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_smp/cortex_a73_smp/gnu/example_build/readme.md b/ports_smp/cortex_a73_smp/gnu/example_build/readme.md
new file mode 100644
index 00000000..3c52a7da
--- /dev/null
+++ b/ports_smp/cortex_a73_smp/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_smp/cortex_a73_smp/gnu/example_build/sample_threadx/sample_threadx.launch b/ports_smp/cortex_a73_smp/gnu/example_build/sample_threadx/sample_threadx.launch
index 1cc749ae..dbd26b95 100644
--- a/ports_smp/cortex_a73_smp/gnu/example_build/sample_threadx/sample_threadx.launch
+++ b/ports_smp/cortex_a73_smp/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"/>
@@ -345,13 +338,13 @@
<listAttribute key="com.arm.debugger.views.common.AddressTracker.debugger.view.DisassemblyView.ranges">
<listEntry value="100"/>
</listAttribute>
- <stringAttribute key="config_db_activity_name" value="Cortex-A35x4 SMP"/>
+ <stringAttribute key="config_db_activity_name" value="Cortex-A73x4 SMP"/>
<stringAttribute key="config_db_connection_keys" value="dtsl_config dtsl_tracecapture_option connect_existing_model dtsl_config_script model_params model_iris config_file model_connection_address setup TCP_KILL_ON_EXIT TCP_DISABLE_EXTENDED_MODE"/>
<stringAttribute key="config_db_connection_type" value="Bare Metal Debug"/>
<stringAttribute key="config_db_platform_name" value="Arm FVP - Base_A73x4"/>
<stringAttribute key="config_db_project_type" value="Bare Metal Debug"/>
<stringAttribute key="config_db_project_type_id" value="BARE_METAL"/>
- <stringAttribute key="config_db_taxonomy_id" value="/platform/armfvp/base_a35x4"/>
+ <stringAttribute key="config_db_taxonomy_id" value="/platform/armfvp/base_a73x4"/>
<stringAttribute key="config_file" value="CDB://iris_config.xml"/>
<booleanAttribute key="connectOnly" value="false"/>
<stringAttribute key="connect_existing_model" value="false"/>
@@ -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-A73x4&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_smp/cortex_a73_smp/gnu/example_build/sample_threadx/semihost_stub.S b/ports_smp/cortex_a73_smp/gnu/example_build/sample_threadx/semihost_stub.S
new file mode 100644
index 00000000..c456875d
--- /dev/null
+++ b/ports_smp/cortex_a73_smp/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_smp/cortex_a73_smp/gnu/inc/tx_port.h b/ports_smp/cortex_a73_smp/gnu/inc/tx_port.h
index e97d78d5..38c86cb2 100644
--- a/ports_smp/cortex_a73_smp/gnu/inc/tx_port.h
+++ b/ports_smp/cortex_a73_smp/gnu/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_smp/cortex_a73_smp/gnu/src/tx_thread_smp_time_get.S b/ports_smp/cortex_a73_smp/gnu/src/tx_thread_smp_time_get.S
index 335824fb..4bb9f1cb 100644
--- a/ports_smp/cortex_a73_smp/gnu/src/tx_thread_smp_time_get.S
+++ b/ports_smp/cortex_a73_smp/gnu/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_smp/cortex_a75_smp/ac6/example_build/sample_threadx/sample_threadx.launch b/ports_smp/cortex_a75_smp/ac6/example_build/sample_threadx/sample_threadx.launch
index 28c5aab8..48c03e62 100644
--- a/ports_smp/cortex_a75_smp/ac6/example_build/sample_threadx/sample_threadx.launch
+++ b/ports_smp/cortex_a75_smp/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;"/>
@@ -316,13 +309,13 @@
<listAttribute key="com.arm.debugger.views.common.AddressTracker.debugger.view.DisassemblyView.ranges">
<listEntry value="100"/>
</listAttribute>
- <stringAttribute key="config_db_activity_name" value="Cortex-A35x4 SMP"/>
+ <stringAttribute key="config_db_activity_name" value="Cortex-A75x4 SMP"/>
<stringAttribute key="config_db_connection_keys" value="dtsl_config dtsl_tracecapture_option connect_existing_model dtsl_config_script model_params model_iris config_file model_connection_address setup TCP_KILL_ON_EXIT TCP_DISABLE_EXTENDED_MODE"/>
<stringAttribute key="config_db_connection_type" value="Bare Metal Debug"/>
<stringAttribute key="config_db_platform_name" value="Arm FVP - Base_A75x4"/>
<stringAttribute key="config_db_project_type" value="Bare Metal Debug"/>
<stringAttribute key="config_db_project_type_id" value="BARE_METAL"/>
- <stringAttribute key="config_db_taxonomy_id" value="/platform/armfvp/base_a35x4"/>
+ <stringAttribute key="config_db_taxonomy_id" value="/platform/armfvp/base_a75x4"/>
<stringAttribute key="config_file" value="CDB://iris_config.xml"/>
<booleanAttribute key="connectOnly" value="false"/>
<stringAttribute key="connect_existing_model" value="false"/>
@@ -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-A75x4&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_smp/cortex_a75_smp/ac6/inc/tx_port.h b/ports_smp/cortex_a75_smp/ac6/inc/tx_port.h
index e97d78d5..38c86cb2 100644
--- a/ports_smp/cortex_a75_smp/ac6/inc/tx_port.h
+++ b/ports_smp/cortex_a75_smp/ac6/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_smp/cortex_a75_smp/ac6/src/tx_thread_smp_time_get.S b/ports_smp/cortex_a75_smp/ac6/src/tx_thread_smp_time_get.S
index 335824fb..4bb9f1cb 100644
--- a/ports_smp/cortex_a75_smp/ac6/src/tx_thread_smp_time_get.S
+++ b/ports_smp/cortex_a75_smp/ac6/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_smp/cortex_a75_smp/gnu/CMakeLists.txt b/ports_smp/cortex_a75_smp/gnu/CMakeLists.txt
new file mode 100644
index 00000000..36f7492b
--- /dev/null
+++ b/ports_smp/cortex_a75_smp/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_smp/cortex_a75_smp/gnu/example_build/build_threadx.sh b/ports_smp/cortex_a75_smp/gnu/example_build/build_threadx.sh
new file mode 100755
index 00000000..b3b2cd36
--- /dev/null
+++ b/ports_smp/cortex_a75_smp/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_smp/cortex_a75_smp/gnu/example_build/build_threadx_sample.sh b/ports_smp/cortex_a75_smp/gnu/example_build/build_threadx_sample.sh
new file mode 100755
index 00000000..94248a88
--- /dev/null
+++ b/ports_smp/cortex_a75_smp/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_smp/cortex_a75_smp/gnu/example_build/readme.md b/ports_smp/cortex_a75_smp/gnu/example_build/readme.md
new file mode 100644
index 00000000..3c52a7da
--- /dev/null
+++ b/ports_smp/cortex_a75_smp/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_smp/cortex_a75_smp/gnu/example_build/sample_threadx/sample_threadx.launch b/ports_smp/cortex_a75_smp/gnu/example_build/sample_threadx/sample_threadx.launch
index 76a6ad45..f2e1d3a7 100644
--- a/ports_smp/cortex_a75_smp/gnu/example_build/sample_threadx/sample_threadx.launch
+++ b/ports_smp/cortex_a75_smp/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"/>
@@ -345,13 +338,13 @@
<listAttribute key="com.arm.debugger.views.common.AddressTracker.debugger.view.DisassemblyView.ranges">
<listEntry value="100"/>
</listAttribute>
- <stringAttribute key="config_db_activity_name" value="Cortex-A35x4 SMP"/>
+ <stringAttribute key="config_db_activity_name" value="Cortex-A75x4 SMP"/>
<stringAttribute key="config_db_connection_keys" value="dtsl_config dtsl_tracecapture_option connect_existing_model dtsl_config_script model_params model_iris config_file model_connection_address setup TCP_KILL_ON_EXIT TCP_DISABLE_EXTENDED_MODE"/>
<stringAttribute key="config_db_connection_type" value="Bare Metal Debug"/>
<stringAttribute key="config_db_platform_name" value="Arm FVP - Base_A75x4"/>
<stringAttribute key="config_db_project_type" value="Bare Metal Debug"/>
<stringAttribute key="config_db_project_type_id" value="BARE_METAL"/>
- <stringAttribute key="config_db_taxonomy_id" value="/platform/armfvp/base_a35x4"/>
+ <stringAttribute key="config_db_taxonomy_id" value="/platform/armfvp/base_a75x4"/>
<stringAttribute key="config_file" value="CDB://iris_config.xml"/>
<booleanAttribute key="connectOnly" value="false"/>
<stringAttribute key="connect_existing_model" value="false"/>
@@ -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-A75x4&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_smp/cortex_a75_smp/gnu/example_build/sample_threadx/semihost_stub.S b/ports_smp/cortex_a75_smp/gnu/example_build/sample_threadx/semihost_stub.S
new file mode 100644
index 00000000..c456875d
--- /dev/null
+++ b/ports_smp/cortex_a75_smp/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_smp/cortex_a75_smp/gnu/inc/tx_port.h b/ports_smp/cortex_a75_smp/gnu/inc/tx_port.h
index 31eb4f24..38c86cb2 100644
--- a/ports_smp/cortex_a75_smp/gnu/inc/tx_port.h
+++ b/ports_smp/cortex_a75_smp/gnu/inc/tx_port.h
@@ -187,7 +187,7 @@ typedef unsigned long long ALIGN_TYPE;
/* Define various constants for the ThreadX ARM port. */
#define TX_INT_DISABLE 0xC0 /* Disable IRQ & FIQ interrupts */
-#define TX_INT_ENABLE 0x00 /* Enable IRQ & FIQ interrupts */
+#define TX_INT_ENABLE 0x00 /* Enable IRQ & FIQ interrupts */
/* Define the clock source for trace event entry time stamp. The following two item are port specific.
@@ -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_smp/cortex_a75_smp/gnu/src/tx_thread_smp_time_get.S b/ports_smp/cortex_a75_smp/gnu/src/tx_thread_smp_time_get.S
index 335824fb..4bb9f1cb 100644
--- a/ports_smp/cortex_a75_smp/gnu/src/tx_thread_smp_time_get.S
+++ b/ports_smp/cortex_a75_smp/gnu/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_smp/cortex_a76_smp/ac6/example_build/sample_threadx/sample_threadx.launch b/ports_smp/cortex_a76_smp/ac6/example_build/sample_threadx/sample_threadx.launch
index a665e8c3..557f8e3e 100644
--- a/ports_smp/cortex_a76_smp/ac6/example_build/sample_threadx/sample_threadx.launch
+++ b/ports_smp/cortex_a76_smp/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;"/>
@@ -316,13 +309,13 @@
<listAttribute key="com.arm.debugger.views.common.AddressTracker.debugger.view.DisassemblyView.ranges">
<listEntry value="100"/>
</listAttribute>
- <stringAttribute key="config_db_activity_name" value="Cortex-A35x4 SMP"/>
+ <stringAttribute key="config_db_activity_name" value="Cortex-A76x4 SMP"/>
<stringAttribute key="config_db_connection_keys" value="dtsl_config dtsl_tracecapture_option connect_existing_model dtsl_config_script model_params model_iris config_file model_connection_address setup TCP_KILL_ON_EXIT TCP_DISABLE_EXTENDED_MODE"/>
<stringAttribute key="config_db_connection_type" value="Bare Metal Debug"/>
<stringAttribute key="config_db_platform_name" value="Arm FVP - Base_A76x4"/>
<stringAttribute key="config_db_project_type" value="Bare Metal Debug"/>
<stringAttribute key="config_db_project_type_id" value="BARE_METAL"/>
- <stringAttribute key="config_db_taxonomy_id" value="/platform/armfvp/base_a35x4"/>
+ <stringAttribute key="config_db_taxonomy_id" value="/platform/armfvp/base_a76x4"/>
<stringAttribute key="config_file" value="CDB://iris_config.xml"/>
<booleanAttribute key="connectOnly" value="false"/>
<stringAttribute key="connect_existing_model" value="false"/>
@@ -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-A76x4&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_smp/cortex_a76_smp/ac6/inc/tx_port.h b/ports_smp/cortex_a76_smp/ac6/inc/tx_port.h
index e97d78d5..38c86cb2 100644
--- a/ports_smp/cortex_a76_smp/ac6/inc/tx_port.h
+++ b/ports_smp/cortex_a76_smp/ac6/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_smp/cortex_a76_smp/ac6/src/tx_thread_smp_time_get.S b/ports_smp/cortex_a76_smp/ac6/src/tx_thread_smp_time_get.S
index 335824fb..4bb9f1cb 100644
--- a/ports_smp/cortex_a76_smp/ac6/src/tx_thread_smp_time_get.S
+++ b/ports_smp/cortex_a76_smp/ac6/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_smp/cortex_a76_smp/gnu/CMakeLists.txt b/ports_smp/cortex_a76_smp/gnu/CMakeLists.txt
new file mode 100644
index 00000000..36f7492b
--- /dev/null
+++ b/ports_smp/cortex_a76_smp/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_smp/cortex_a76_smp/gnu/example_build/build_threadx.sh b/ports_smp/cortex_a76_smp/gnu/example_build/build_threadx.sh
new file mode 100755
index 00000000..b3b2cd36
--- /dev/null
+++ b/ports_smp/cortex_a76_smp/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_smp/cortex_a76_smp/gnu/example_build/build_threadx_sample.sh b/ports_smp/cortex_a76_smp/gnu/example_build/build_threadx_sample.sh
new file mode 100755
index 00000000..94248a88
--- /dev/null
+++ b/ports_smp/cortex_a76_smp/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_smp/cortex_a76_smp/gnu/example_build/readme.md b/ports_smp/cortex_a76_smp/gnu/example_build/readme.md
new file mode 100644
index 00000000..3c52a7da
--- /dev/null
+++ b/ports_smp/cortex_a76_smp/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_smp/cortex_a76_smp/gnu/example_build/sample_threadx/sample_threadx.launch b/ports_smp/cortex_a76_smp/gnu/example_build/sample_threadx/sample_threadx.launch
index 58967dca..ef5c7bf7 100644
--- a/ports_smp/cortex_a76_smp/gnu/example_build/sample_threadx/sample_threadx.launch
+++ b/ports_smp/cortex_a76_smp/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"/>
@@ -345,13 +338,13 @@
<listAttribute key="com.arm.debugger.views.common.AddressTracker.debugger.view.DisassemblyView.ranges">
<listEntry value="100"/>
</listAttribute>
- <stringAttribute key="config_db_activity_name" value="Cortex-A35x4 SMP"/>
+ <stringAttribute key="config_db_activity_name" value="Cortex-A76x4 SMP"/>
<stringAttribute key="config_db_connection_keys" value="dtsl_config dtsl_tracecapture_option connect_existing_model dtsl_config_script model_params model_iris config_file model_connection_address setup TCP_KILL_ON_EXIT TCP_DISABLE_EXTENDED_MODE"/>
<stringAttribute key="config_db_connection_type" value="Bare Metal Debug"/>
<stringAttribute key="config_db_platform_name" value="Arm FVP - Base_A76x4"/>
<stringAttribute key="config_db_project_type" value="Bare Metal Debug"/>
<stringAttribute key="config_db_project_type_id" value="BARE_METAL"/>
- <stringAttribute key="config_db_taxonomy_id" value="/platform/armfvp/base_a35x4"/>
+ <stringAttribute key="config_db_taxonomy_id" value="/platform/armfvp/base_a76x4"/>
<stringAttribute key="config_file" value="CDB://iris_config.xml"/>
<booleanAttribute key="connectOnly" value="false"/>
<stringAttribute key="connect_existing_model" value="false"/>
@@ -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-A76x4&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_smp/cortex_a76_smp/gnu/example_build/sample_threadx/semihost_stub.S b/ports_smp/cortex_a76_smp/gnu/example_build/sample_threadx/semihost_stub.S
new file mode 100644
index 00000000..c456875d
--- /dev/null
+++ b/ports_smp/cortex_a76_smp/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_smp/cortex_a76_smp/gnu/inc/tx_port.h b/ports_smp/cortex_a76_smp/gnu/inc/tx_port.h
index e97d78d5..38c86cb2 100644
--- a/ports_smp/cortex_a76_smp/gnu/inc/tx_port.h
+++ b/ports_smp/cortex_a76_smp/gnu/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_smp/cortex_a76_smp/gnu/src/tx_thread_smp_time_get.S b/ports_smp/cortex_a76_smp/gnu/src/tx_thread_smp_time_get.S
index 335824fb..4bb9f1cb 100644
--- a/ports_smp/cortex_a76_smp/gnu/src/tx_thread_smp_time_get.S
+++ b/ports_smp/cortex_a76_smp/gnu/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_smp/cortex_a76ae_smp/ac6/example_build/sample_threadx/sample_threadx.launch b/ports_smp/cortex_a76ae_smp/ac6/example_build/sample_threadx/sample_threadx.launch
index f261e124..b140704f 100644
--- a/ports_smp/cortex_a76ae_smp/ac6/example_build/sample_threadx/sample_threadx.launch
+++ b/ports_smp/cortex_a76ae_smp/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;"/>
@@ -316,13 +309,13 @@
<listAttribute key="com.arm.debugger.views.common.AddressTracker.debugger.view.DisassemblyView.ranges">
<listEntry value="100"/>
</listAttribute>
- <stringAttribute key="config_db_activity_name" value="Cortex-A35x4 SMP"/>
+ <stringAttribute key="config_db_activity_name" value="Cortex-A76AEx4 SMP"/>
<stringAttribute key="config_db_connection_keys" value="dtsl_config dtsl_tracecapture_option connect_existing_model dtsl_config_script model_params model_iris config_file model_connection_address setup TCP_KILL_ON_EXIT TCP_DISABLE_EXTENDED_MODE"/>
<stringAttribute key="config_db_connection_type" value="Bare Metal Debug"/>
<stringAttribute key="config_db_platform_name" value="Arm FVP - Base_A76AEx4"/>
<stringAttribute key="config_db_project_type" value="Bare Metal Debug"/>
<stringAttribute key="config_db_project_type_id" value="BARE_METAL"/>
- <stringAttribute key="config_db_taxonomy_id" value="/platform/armfvp/base_a35x4"/>
+ <stringAttribute key="config_db_taxonomy_id" value="/platform/armfvp/base_a76aex4"/>
<stringAttribute key="config_file" value="CDB://iris_config.xml"/>
<booleanAttribute key="connectOnly" value="false"/>
<stringAttribute key="connect_existing_model" value="false"/>
@@ -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-A76AEx4&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_smp/cortex_a76ae_smp/ac6/inc/tx_port.h b/ports_smp/cortex_a76ae_smp/ac6/inc/tx_port.h
index e97d78d5..38c86cb2 100644
--- a/ports_smp/cortex_a76ae_smp/ac6/inc/tx_port.h
+++ b/ports_smp/cortex_a76ae_smp/ac6/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_smp/cortex_a76ae_smp/ac6/src/tx_thread_smp_time_get.S b/ports_smp/cortex_a76ae_smp/ac6/src/tx_thread_smp_time_get.S
index 335824fb..4bb9f1cb 100644
--- a/ports_smp/cortex_a76ae_smp/ac6/src/tx_thread_smp_time_get.S
+++ b/ports_smp/cortex_a76ae_smp/ac6/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_smp/cortex_a76ae_smp/gnu/CMakeLists.txt b/ports_smp/cortex_a76ae_smp/gnu/CMakeLists.txt
new file mode 100644
index 00000000..36f7492b
--- /dev/null
+++ b/ports_smp/cortex_a76ae_smp/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_smp/cortex_a76ae_smp/gnu/example_build/build_threadx.sh b/ports_smp/cortex_a76ae_smp/gnu/example_build/build_threadx.sh
new file mode 100755
index 00000000..b3b2cd36
--- /dev/null
+++ b/ports_smp/cortex_a76ae_smp/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_smp/cortex_a76ae_smp/gnu/example_build/build_threadx_sample.sh b/ports_smp/cortex_a76ae_smp/gnu/example_build/build_threadx_sample.sh
new file mode 100755
index 00000000..94248a88
--- /dev/null
+++ b/ports_smp/cortex_a76ae_smp/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_smp/cortex_a76ae_smp/gnu/example_build/readme.md b/ports_smp/cortex_a76ae_smp/gnu/example_build/readme.md
new file mode 100644
index 00000000..3c52a7da
--- /dev/null
+++ b/ports_smp/cortex_a76ae_smp/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_smp/cortex_a76ae_smp/gnu/example_build/sample_threadx/sample_threadx.launch b/ports_smp/cortex_a76ae_smp/gnu/example_build/sample_threadx/sample_threadx.launch
index 8108d076..44fc82c0 100644
--- a/ports_smp/cortex_a76ae_smp/gnu/example_build/sample_threadx/sample_threadx.launch
+++ b/ports_smp/cortex_a76ae_smp/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"/>
@@ -345,13 +338,13 @@
<listAttribute key="com.arm.debugger.views.common.AddressTracker.debugger.view.DisassemblyView.ranges">
<listEntry value="100"/>
</listAttribute>
- <stringAttribute key="config_db_activity_name" value="Cortex-A35x4 SMP"/>
+ <stringAttribute key="config_db_activity_name" value="Cortex-A76AEx4 SMP"/>
<stringAttribute key="config_db_connection_keys" value="dtsl_config dtsl_tracecapture_option connect_existing_model dtsl_config_script model_params model_iris config_file model_connection_address setup TCP_KILL_ON_EXIT TCP_DISABLE_EXTENDED_MODE"/>
<stringAttribute key="config_db_connection_type" value="Bare Metal Debug"/>
<stringAttribute key="config_db_platform_name" value="Arm FVP - Base_A76AEx4"/>
<stringAttribute key="config_db_project_type" value="Bare Metal Debug"/>
<stringAttribute key="config_db_project_type_id" value="BARE_METAL"/>
- <stringAttribute key="config_db_taxonomy_id" value="/platform/armfvp/base_a35x4"/>
+ <stringAttribute key="config_db_taxonomy_id" value="/platform/armfvp/base_a76aex4"/>
<stringAttribute key="config_file" value="CDB://iris_config.xml"/>
<booleanAttribute key="connectOnly" value="false"/>
<stringAttribute key="connect_existing_model" value="false"/>
@@ -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-A76AEx4&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_smp/cortex_a76ae_smp/gnu/example_build/sample_threadx/semihost_stub.S b/ports_smp/cortex_a76ae_smp/gnu/example_build/sample_threadx/semihost_stub.S
new file mode 100644
index 00000000..c456875d
--- /dev/null
+++ b/ports_smp/cortex_a76ae_smp/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_smp/cortex_a76ae_smp/gnu/inc/tx_port.h b/ports_smp/cortex_a76ae_smp/gnu/inc/tx_port.h
index e97d78d5..38c86cb2 100644
--- a/ports_smp/cortex_a76ae_smp/gnu/inc/tx_port.h
+++ b/ports_smp/cortex_a76ae_smp/gnu/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_smp/cortex_a76ae_smp/gnu/src/tx_thread_smp_time_get.S b/ports_smp/cortex_a76ae_smp/gnu/src/tx_thread_smp_time_get.S
index 335824fb..4bb9f1cb 100644
--- a/ports_smp/cortex_a76ae_smp/gnu/src/tx_thread_smp_time_get.S
+++ b/ports_smp/cortex_a76ae_smp/gnu/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_smp/cortex_a77_smp/ac6/example_build/sample_threadx/sample_threadx.launch b/ports_smp/cortex_a77_smp/ac6/example_build/sample_threadx/sample_threadx.launch
index 8d2fe10c..956df926 100644
--- a/ports_smp/cortex_a77_smp/ac6/example_build/sample_threadx/sample_threadx.launch
+++ b/ports_smp/cortex_a77_smp/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;"/>
@@ -316,13 +309,13 @@
<listAttribute key="com.arm.debugger.views.common.AddressTracker.debugger.view.DisassemblyView.ranges">
<listEntry value="100"/>
</listAttribute>
- <stringAttribute key="config_db_activity_name" value="Cortex-A35x4 SMP"/>
+ <stringAttribute key="config_db_activity_name" value="Cortex-A77x4 SMP"/>
<stringAttribute key="config_db_connection_keys" value="dtsl_config dtsl_tracecapture_option connect_existing_model dtsl_config_script model_params model_iris config_file model_connection_address setup TCP_KILL_ON_EXIT TCP_DISABLE_EXTENDED_MODE"/>
<stringAttribute key="config_db_connection_type" value="Bare Metal Debug"/>
<stringAttribute key="config_db_platform_name" value="Arm FVP - Base_A77x4"/>
<stringAttribute key="config_db_project_type" value="Bare Metal Debug"/>
<stringAttribute key="config_db_project_type_id" value="BARE_METAL"/>
- <stringAttribute key="config_db_taxonomy_id" value="/platform/armfvp/base_a35x4"/>
+ <stringAttribute key="config_db_taxonomy_id" value="/platform/armfvp/base_a77x4"/>
<stringAttribute key="config_file" value="CDB://iris_config.xml"/>
<booleanAttribute key="connectOnly" value="false"/>
<stringAttribute key="connect_existing_model" value="false"/>
@@ -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-A77x4&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_smp/cortex_a77_smp/ac6/inc/tx_port.h b/ports_smp/cortex_a77_smp/ac6/inc/tx_port.h
index e97d78d5..38c86cb2 100644
--- a/ports_smp/cortex_a77_smp/ac6/inc/tx_port.h
+++ b/ports_smp/cortex_a77_smp/ac6/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_smp/cortex_a77_smp/ac6/src/tx_thread_smp_time_get.S b/ports_smp/cortex_a77_smp/ac6/src/tx_thread_smp_time_get.S
index 335824fb..4bb9f1cb 100644
--- a/ports_smp/cortex_a77_smp/ac6/src/tx_thread_smp_time_get.S
+++ b/ports_smp/cortex_a77_smp/ac6/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_smp/cortex_a77_smp/gnu/CMakeLists.txt b/ports_smp/cortex_a77_smp/gnu/CMakeLists.txt
new file mode 100644
index 00000000..36f7492b
--- /dev/null
+++ b/ports_smp/cortex_a77_smp/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_smp/cortex_a77_smp/gnu/example_build/build_threadx.sh b/ports_smp/cortex_a77_smp/gnu/example_build/build_threadx.sh
new file mode 100755
index 00000000..b3b2cd36
--- /dev/null
+++ b/ports_smp/cortex_a77_smp/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_smp/cortex_a77_smp/gnu/example_build/build_threadx_sample.sh b/ports_smp/cortex_a77_smp/gnu/example_build/build_threadx_sample.sh
new file mode 100755
index 00000000..94248a88
--- /dev/null
+++ b/ports_smp/cortex_a77_smp/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_smp/cortex_a77_smp/gnu/example_build/readme.md b/ports_smp/cortex_a77_smp/gnu/example_build/readme.md
new file mode 100644
index 00000000..3c52a7da
--- /dev/null
+++ b/ports_smp/cortex_a77_smp/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_smp/cortex_a77_smp/gnu/example_build/sample_threadx/sample_threadx.launch b/ports_smp/cortex_a77_smp/gnu/example_build/sample_threadx/sample_threadx.launch
index a7f12edc..e33dfa12 100644
--- a/ports_smp/cortex_a77_smp/gnu/example_build/sample_threadx/sample_threadx.launch
+++ b/ports_smp/cortex_a77_smp/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"/>
@@ -345,13 +338,13 @@
<listAttribute key="com.arm.debugger.views.common.AddressTracker.debugger.view.DisassemblyView.ranges">
<listEntry value="100"/>
</listAttribute>
- <stringAttribute key="config_db_activity_name" value="Cortex-A35x4 SMP"/>
+ <stringAttribute key="config_db_activity_name" value="Cortex-A77x4 SMP"/>
<stringAttribute key="config_db_connection_keys" value="dtsl_config dtsl_tracecapture_option connect_existing_model dtsl_config_script model_params model_iris config_file model_connection_address setup TCP_KILL_ON_EXIT TCP_DISABLE_EXTENDED_MODE"/>
<stringAttribute key="config_db_connection_type" value="Bare Metal Debug"/>
<stringAttribute key="config_db_platform_name" value="Arm FVP - Base_A77x4"/>
<stringAttribute key="config_db_project_type" value="Bare Metal Debug"/>
<stringAttribute key="config_db_project_type_id" value="BARE_METAL"/>
- <stringAttribute key="config_db_taxonomy_id" value="/platform/armfvp/base_a35x4"/>
+ <stringAttribute key="config_db_taxonomy_id" value="/platform/armfvp/base_a77x4"/>
<stringAttribute key="config_file" value="CDB://iris_config.xml"/>
<booleanAttribute key="connectOnly" value="false"/>
<stringAttribute key="connect_existing_model" value="false"/>
@@ -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-A77x4&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_smp/cortex_a77_smp/gnu/example_build/sample_threadx/semihost_stub.S b/ports_smp/cortex_a77_smp/gnu/example_build/sample_threadx/semihost_stub.S
new file mode 100644
index 00000000..c456875d
--- /dev/null
+++ b/ports_smp/cortex_a77_smp/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_smp/cortex_a77_smp/gnu/inc/tx_port.h b/ports_smp/cortex_a77_smp/gnu/inc/tx_port.h
index e97d78d5..38c86cb2 100644
--- a/ports_smp/cortex_a77_smp/gnu/inc/tx_port.h
+++ b/ports_smp/cortex_a77_smp/gnu/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_smp/cortex_a77_smp/gnu/src/tx_thread_smp_time_get.S b/ports_smp/cortex_a77_smp/gnu/src/tx_thread_smp_time_get.S
index 335824fb..4bb9f1cb 100644
--- a/ports_smp/cortex_a77_smp/gnu/src/tx_thread_smp_time_get.S
+++ b/ports_smp/cortex_a77_smp/gnu/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_smp/cortex_a78_smp/ac6/example_build/sample_threadx/.cproject b/ports_smp/cortex_a78_smp/ac6/example_build/sample_threadx/.cproject
index 67ef2a0c..4e305710 100644
--- a/ports_smp/cortex_a78_smp/ac6/example_build/sample_threadx/.cproject
+++ b/ports_smp/cortex_a78_smp/ac6/example_build/sample_threadx/.cproject
@@ -29,7 +29,7 @@
<toolChain id="com.arm.toolchain.v6.base.var.arm_compiler_6-6.1592753597" name="Arm Compiler 6" superClass="com.arm.toolchain.v6.base.var.arm_compiler_6-6">
- <option id="com.arm.toolchain.v6.base.options.target.cpu_fpu.1337922098" superClass="com.arm.toolchain.v6.base.options.target.cpu_fpu" useByScannerDiscovery="false" value="cortex-a78.AArch64.ARMv8.Neon.Crypto" valueType="string"/>
+ <option id="com.arm.toolchain.v6.base.options.target.cpu_fpu.1337922098" superClass="com.arm.toolchain.v6.base.options.target.cpu_fpu" useByScannerDiscovery="false" value="Cortex-A78.AArch64.ARMv8.Neon.Crypto" valueType="string"/>
<targetPlatform id="com.arm.toolchain.v6.base.var.arm_compiler_6-6.1592753597.2060144338" name=""/>
diff --git a/ports_smp/cortex_a78_smp/ac6/example_build/sample_threadx/sample_threadx.launch b/ports_smp/cortex_a78_smp/ac6/example_build/sample_threadx/sample_threadx.launch
index 9aefbdcd..aac92dec 100644
--- a/ports_smp/cortex_a78_smp/ac6/example_build/sample_threadx/sample_threadx.launch
+++ b/ports_smp/cortex_a78_smp/ac6/example_build/sample_threadx/sample_threadx.launch
@@ -6,17 +6,17 @@
<stringAttribute key="ANDROID_PROCESS_NAME" value=""/>
<mapAttribute key="AverageDurationTracker">
<mapEntry key="*Fetching Data" value="34126331"/>
- <mapEntry key="*Fetching Data Model" value="1439173"/>
+ <mapEntry key="*Fetching Data Model" value="1887986"/>
<mapEntry key="*FunctionLoader" value="137168653"/>
- <mapEntry key="*list global low level symbols" value="2707112"/>
+ <mapEntry key="*list global low level symbols" value="3163826"/>
<mapEntry key="*loading memory from target" value="2367919"/>
- <mapEntry key="*loading values from target" value="8477514"/>
+ <mapEntry key="*loading values from target" value="8665557"/>
<mapEntry key="*trace" value="1527238"/>
- <mapEntry key="*updating expressions" value="101886453"/>
+ <mapEntry key="*updating expressions" value="25251903"/>
<mapEntry key="*updating local_variables" value="836905"/>
<mapEntry key="*updating registers" value="97090462"/>
<mapEntry key="*updating variables" value="877039"/>
- <mapEntry key="AddEventObserver" value="6587743"/>
+ <mapEntry key="AddEventObserver" value="5292071"/>
<mapEntry key="Evaluate" value="1689813"/>
<mapEntry key="ResumeToHere" value="20159012"/>
<mapEntry key="Retrieving globals list" value="21298708"/>
@@ -24,11 +24,11 @@
<mapEntry key="backtrace" value="21505977"/>
<mapEntry key="break" value="9764564"/>
<mapEntry key="checking tracepoints" value="372731"/>
- <mapEntry key="compute execution mode" value="557345"/>
+ <mapEntry key="compute execution mode" value="835755"/>
<mapEntry key="console" value="11946310"/>
- <mapEntry key="continue" value="12697403"/>
+ <mapEntry key="continue" value="21247618"/>
<mapEntry key="core" value="5451456"/>
- <mapEntry key="directory" value="4737162"/>
+ <mapEntry key="directory" value="4479981"/>
<mapEntry key="disable" value="2444670"/>
<mapEntry key="disassemble" value="64135505"/>
<mapEntry key="enable" value="5445745"/>
@@ -36,40 +36,41 @@
<mapEntry key="evaluate address" value="1056014"/>
<mapEntry key="finish" value="20115248"/>
<mapEntry key="get byte order" value="633302"/>
- <mapEntry key="get capabilities" value="548556"/>
- <mapEntry key="get execution addresss" value="438164"/>
- <mapEntry key="get source lines" value="3151194"/>
- <mapEntry key="get substitute paths" value="293110"/>
+ <mapEntry key="get capabilities" value="382078"/>
+ <mapEntry key="get execution addresss" value="403253"/>
+ <mapEntry key="get source lines" value="951928"/>
+ <mapEntry key="get substitute paths" value="523052"/>
<mapEntry key="getValidEncodings" value="1202320"/>
- <mapEntry key="initialize command help" value="68196070"/>
+ <mapEntry key="initialize command help" value="63855085"/>
<mapEntry key="interrupt" value="11210435"/>
- <mapEntry key="list breakpoint options" value="1264804"/>
- <mapEntry key="list breakpoints" value="1473749"/>
- <mapEntry key="list instruction sets" value="1512051"/>
- <mapEntry key="list signals" value="1314040"/>
+ <mapEntry key="list breakpoint options" value="2030851"/>
+ <mapEntry key="list breakpoints" value="1627224"/>
+ <mapEntry key="list instruction sets" value="1847125"/>
+ <mapEntry key="list signals" value="1953020"/>
<mapEntry key="list source files" value="573423"/>
- <mapEntry key="list watchpoint options" value="4130737"/>
- <mapEntry key="list watchpoints" value="739118"/>
- <mapEntry key="loadfile" value="308178719"/>
+ <mapEntry key="list watchpoint options" value="6057468"/>
+ <mapEntry key="list watchpoints" value="970059"/>
+ <mapEntry key="loadfile" value="386648009"/>
<mapEntry key="next" value="24266800"/>
<mapEntry key="query supports threads" value="215433"/>
- <mapEntry key="remove" value="3597385"/>
- <mapEntry key="run script" value="37326822"/>
- <mapEntry key="set CWD" value="4366642"/>
+ <mapEntry key="remove" value="7663692"/>
+ <mapEntry key="run script" value="44460661"/>
+ <mapEntry key="set CWD" value="5180571"/>
<mapEntry key="set breakpoint properties" value="10666013"/>
- <mapEntry key="set debug-from" value="1215725"/>
- <mapEntry key="set substitute-path" value="23083827"/>
- <mapEntry key="source use_model_semihosting.ds" value="7540462"/>
- <mapEntry key="start" value="36728254"/>
+ <mapEntry key="set debug-from" value="1157012"/>
+ <mapEntry key="set substitute-path" value="27245163"/>
+ <mapEntry key="source use_model_semihosting.ds" value="8849881"/>
+ <mapEntry key="start" value="50528177"/>
<mapEntry key="step" value="26461127"/>
<mapEntry key="stepi" value="29574773"/>
<mapEntry key="synchronizing trace ranges" value="21582"/>
<mapEntry key="target reset" value="32992642"/>
- <mapEntry key="toggleBreakpoint" value="7875634"/>
+ <mapEntry key="toggleBreakpoint" value="19462208"/>
<mapEntry key="updateBreakpointLocation" value="1868000"/>
- <mapEntry key="waitForTargetToStop" value="47515299"/>
+ <mapEntry key="waitForTargetToStop" value="52570549"/>
<mapEntry key="write expression" value="21220700"/>
</mapAttribute>
+ <stringAttribute key="CLOCK_SPEED" value="Auto"/>
<listAttribute key="DEBUG_TAB."/>
<stringAttribute key="DEBUG_TAB..RESOURCES.0.TYPE" value="SOURCE_DIR"/>
<stringAttribute key="DEBUG_TAB..RESOURCES.0.VALUE" value="${workspace_loc:/sample_threadx}"/>
@@ -89,15 +90,15 @@
<stringAttribute key="FILES.DEBUG_RESIDENT_ANDROID.RESOURCES.0.VALUE" value=""/>
<intAttribute key="FILES.DEBUG_RESIDENT_ANDROID.RESOURCES.COUNT" value="1"/>
<listAttribute key="FILES.DEBUG_RESIDENT_APP"/>
- <stringAttribute key="FILES.DEBUG_RESIDENT_APP.RESOURCES.0.TYPE" value="TARGET_WORKING_DIR"/>
+ <stringAttribute key="FILES.DEBUG_RESIDENT_APP.RESOURCES.0.TYPE" value="APPLICATION_ON_TARGET"/>
<stringAttribute key="FILES.DEBUG_RESIDENT_APP.RESOURCES.0.VALUE" value=""/>
- <stringAttribute key="FILES.DEBUG_RESIDENT_APP.RESOURCES.1.TYPE" value="APPLICATION_ON_TARGET"/>
+ <stringAttribute key="FILES.DEBUG_RESIDENT_APP.RESOURCES.1.TYPE" value="TARGET_WORKING_DIR"/>
<stringAttribute key="FILES.DEBUG_RESIDENT_APP.RESOURCES.1.VALUE" value=""/>
<intAttribute key="FILES.DEBUG_RESIDENT_APP.RESOURCES.COUNT" value="2"/>
<listAttribute key="FILES.DOWNLOAD_AND_DEBUG"/>
<stringAttribute key="FILES.DOWNLOAD_AND_DEBUG.RESOURCES.0.OPTION.ALSO_LOAD_SYMBOLS" value="false"/>
<stringAttribute key="FILES.DOWNLOAD_AND_DEBUG.RESOURCES.0.OPTION.ON_DEMAND_LOAD" value="true"/>
- <stringAttribute key="FILES.DOWNLOAD_AND_DEBUG.RESOURCES.0.TYPE" value="TARGET_WORKING_DIR"/>
+ <stringAttribute key="FILES.DOWNLOAD_AND_DEBUG.RESOURCES.0.TYPE" value="TARGET_DOWNLOAD_DIR"/>
<stringAttribute key="FILES.DOWNLOAD_AND_DEBUG.RESOURCES.0.VALUE" value=""/>
<stringAttribute key="FILES.DOWNLOAD_AND_DEBUG.RESOURCES.1.OPTION.ALSO_LOAD_SYMBOLS" value="false"/>
<stringAttribute key="FILES.DOWNLOAD_AND_DEBUG.RESOURCES.1.OPTION.ON_DEMAND_LOAD" value="true"/>
@@ -105,13 +106,13 @@
<stringAttribute key="FILES.DOWNLOAD_AND_DEBUG.RESOURCES.1.VALUE" value=""/>
<stringAttribute key="FILES.DOWNLOAD_AND_DEBUG.RESOURCES.2.OPTION.ALSO_LOAD_SYMBOLS" value="false"/>
<stringAttribute key="FILES.DOWNLOAD_AND_DEBUG.RESOURCES.2.OPTION.ON_DEMAND_LOAD" value="true"/>
- <stringAttribute key="FILES.DOWNLOAD_AND_DEBUG.RESOURCES.2.TYPE" value="TARGET_DOWNLOAD_DIR"/>
+ <stringAttribute key="FILES.DOWNLOAD_AND_DEBUG.RESOURCES.2.TYPE" value="TARGET_WORKING_DIR"/>
<stringAttribute key="FILES.DOWNLOAD_AND_DEBUG.RESOURCES.2.VALUE" value=""/>
<intAttribute key="FILES.DOWNLOAD_AND_DEBUG.RESOURCES.COUNT" value="3"/>
<listAttribute key="FILES.DOWNLOAD_DEBUG"/>
<stringAttribute key="FILES.DOWNLOAD_DEBUG.RESOURCES.0.OPTION.ALSO_LOAD_SYMBOLS" value="false"/>
<stringAttribute key="FILES.DOWNLOAD_DEBUG.RESOURCES.0.OPTION.ON_DEMAND_LOAD" value="true"/>
- <stringAttribute key="FILES.DOWNLOAD_DEBUG.RESOURCES.0.TYPE" value="TARGET_WORKING_DIR"/>
+ <stringAttribute key="FILES.DOWNLOAD_DEBUG.RESOURCES.0.TYPE" value="TARGET_DOWNLOAD_DIR"/>
<stringAttribute key="FILES.DOWNLOAD_DEBUG.RESOURCES.0.VALUE" value=""/>
<stringAttribute key="FILES.DOWNLOAD_DEBUG.RESOURCES.1.OPTION.ALSO_LOAD_SYMBOLS" value="false"/>
<stringAttribute key="FILES.DOWNLOAD_DEBUG.RESOURCES.1.OPTION.ON_DEMAND_LOAD" value="true"/>
@@ -119,7 +120,7 @@
<stringAttribute key="FILES.DOWNLOAD_DEBUG.RESOURCES.1.VALUE" value=""/>
<stringAttribute key="FILES.DOWNLOAD_DEBUG.RESOURCES.2.OPTION.ALSO_LOAD_SYMBOLS" value="false"/>
<stringAttribute key="FILES.DOWNLOAD_DEBUG.RESOURCES.2.OPTION.ON_DEMAND_LOAD" value="true"/>
- <stringAttribute key="FILES.DOWNLOAD_DEBUG.RESOURCES.2.TYPE" value="TARGET_DOWNLOAD_DIR"/>
+ <stringAttribute key="FILES.DOWNLOAD_DEBUG.RESOURCES.2.TYPE" value="TARGET_WORKING_DIR"/>
<stringAttribute key="FILES.DOWNLOAD_DEBUG.RESOURCES.2.VALUE" value=""/>
<intAttribute key="FILES.DOWNLOAD_DEBUG.RESOURCES.COUNT" value="3"/>
<intAttribute key="FILES.DOWNLOAD_DEBUG_ANDROID.RESOURCES.COUNT" value="0"/>
@@ -162,6 +163,8 @@
<intAttribute key="POST_TRIGGER_CAPTURE_SIZE" value="50"/>
<booleanAttribute key="RSE_USE_HOSTNAME" value="true"/>
<booleanAttribute key="STOP_ON_TRIGGER" value="false"/>
+ <booleanAttribute key="SWD" value="false"/>
+ <booleanAttribute key="SWJ" value="true"/>
<stringAttribute key="TCP_DISABLE_EXTENDED_MODE" value="true"/>
<booleanAttribute key="TCP_KILL_ON_EXIT" value="false"/>
<listAttribute key="TREE_NODE_PROPERTIES:debugger.view.ExpressionsView">
@@ -211,13 +214,6 @@
<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"/>
@@ -313,13 +309,13 @@
<listAttribute key="com.arm.debugger.views.common.AddressTracker.debugger.view.DisassemblyView.ranges">
<listEntry value="100"/>
</listAttribute>
- <stringAttribute key="config_db_activity_name" value="Cortex-A35x4 SMP"/>
+ <stringAttribute key="config_db_activity_name" value="Cortex-A78x4 SMP"/>
<stringAttribute key="config_db_connection_keys" value="dtsl_config dtsl_tracecapture_option connect_existing_model dtsl_config_script model_params model_iris config_file model_connection_address setup TCP_KILL_ON_EXIT TCP_DISABLE_EXTENDED_MODE"/>
<stringAttribute key="config_db_connection_type" value="Bare Metal Debug"/>
- <stringAttribute key="config_db_platform_name" value="Arm FVP - Base_A35x4"/>
+ <stringAttribute key="config_db_platform_name" value="Arm FVP - Base_A78x4"/>
<stringAttribute key="config_db_project_type" value="Bare Metal Debug"/>
<stringAttribute key="config_db_project_type_id" value="BARE_METAL"/>
- <stringAttribute key="config_db_taxonomy_id" value="/platform/armfvp/base_a35x4"/>
+ <stringAttribute key="config_db_taxonomy_id" value="/platform/armfvp/base_a78x4"/>
<stringAttribute key="config_file" value="CDB://iris_config.xml"/>
<booleanAttribute key="connectOnly" value="false"/>
<stringAttribute key="connect_existing_model" value="false"/>
@@ -363,7 +359,7 @@
<mapEntry key="6" value="NODE_TRANSFER_ELEMENT_COUNT,0;NODE_TRANSFER_ELEMENT_SIZE_IN_BYTES,4;NODE_TYPE,VALUE;FORMATTER,Unsigned Decimal"/>
<mapEntry key="7" value="NODE_TRANSFER_ELEMENT_COUNT,0;NODE_TRANSFER_ELEMENT_SIZE_IN_BYTES,4;NODE_TYPE,VALUE;FORMATTER,Unsigned Decimal"/>
</mapAttribute>
- <stringAttribute key="debugger.view.ExpressionsView:DebugOutlineColumnState" value="OutlineConfig1&#9;8&#9;0&#9;true&#9;true&#9;187&#9;-1&#9;true&#9;1&#9;false&#9;true&#9;90&#9;-1&#9;true&#9;2&#9;true&#9;true&#9;108&#9;-1&#9;true&#9;3&#9;true&#9;true&#9;57&#9;-1&#9;true&#9;4&#9;true&#9;true&#9;50&#9;-1&#9;true&#9;5&#9;true&#9;true&#9;37&#9;-1&#9;true&#9;6&#9;true&#9;true&#9;148&#9;-1&#9;true&#9;7&#9;true&#9;true&#9;53&#9;-1&#9;true"/>
+ <stringAttribute key="debugger.view.ExpressionsView:DebugOutlineColumnState" value="OutlineConfig1&#9;8&#9;0&#9;true&#9;true&#9;255&#9;-1&#9;true&#9;1&#9;false&#9;true&#9;127&#9;-1&#9;true&#9;2&#9;true&#9;true&#9;159&#9;-1&#9;true&#9;3&#9;true&#9;true&#9;75&#9;-1&#9;true&#9;4&#9;true&#9;true&#9;65&#9;-1&#9;true&#9;5&#9;true&#9;true&#9;48&#9;-1&#9;true&#9;6&#9;true&#9;true&#9;241&#9;-1&#9;true&#9;7&#9;true&#9;true&#9;69&#9;-1&#9;true"/>
<stringAttribute key="debugger.view.MemoryView" value="&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot;?&gt;&#10;&lt;page&gt;&#10;&#9;&lt;memoryView/&gt;&#10;&lt;/page&gt;&#10;"/>
<listAttribute key="debugger.view.MemoryView:current">
<listEntry value=""/>
@@ -386,24 +382,16 @@
<stringAttribute key="dtsl_options_file" value="default"/>
<stringAttribute key="dtsl_tracecapture_option" value="options.trace.traceCapture"/>
<booleanAttribute key="linuxOS" value="false"/>
- <stringAttribute key="model_connection_address" value=""/>
+ <stringAttribute key="model_connection_address" value="127.0.0.1:7100"/>
<stringAttribute key="model_iris" value="1"/>
<stringAttribute key="model_params" value="-C bp.secure_memory=false -C cache_state_modelled=0"/>
<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\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;"/>
+ <listEntry value="&quot;FVP_Base_Cortex-A78x4&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_smp/cortex_a78_smp/ac6/example_build/tx/.cproject b/ports_smp/cortex_a78_smp/ac6/example_build/tx/.cproject
index 5896ab3a..c049b3a6 100644
--- a/ports_smp/cortex_a78_smp/ac6/example_build/tx/.cproject
+++ b/ports_smp/cortex_a78_smp/ac6/example_build/tx/.cproject
@@ -7,7 +7,19 @@
<storageModule buildSystemId="org.eclipse.cdt.managedbuilder.core.configurationDataProvider" id="com.arm.eclipse.build.config.v6.lib.debug.base.1470528944" moduleId="org.eclipse.cdt.core.settings" name="Debug">
- <externalSettings/>
+ <externalSettings>
+
+ <externalSetting>
+
+ <entry flags="VALUE_WORKSPACE_PATH" kind="includePath" name="/tx"/>
+
+ <entry flags="VALUE_WORKSPACE_PATH" kind="libraryPath" name="/tx/Debug"/>
+
+ <entry flags="RESOLVED" kind="libraryFile" name="tx" srcPrefixMapping="" srcRootPath=""/>
+
+ </externalSetting>
+
+ </externalSettings>
<extensions>
@@ -29,7 +41,7 @@
<toolChain id="com.arm.toolchain.v6.lib.debug.base.var.arm_compiler_6-6.1684503312" name="Arm Compiler 6" superClass="com.arm.toolchain.v6.lib.debug.base.var.arm_compiler_6-6">
- <option id="com.arm.toolchain.v6.base.options.target.cpu_fpu.982423385" superClass="com.arm.toolchain.v6.base.options.target.cpu_fpu" useByScannerDiscovery="false" value="cortex-a78.AArch64.ARMv8.Neon.Crypto" valueType="string"/>
+ <option id="com.arm.toolchain.v6.base.options.target.cpu_fpu.982423385" superClass="com.arm.toolchain.v6.base.options.target.cpu_fpu" useByScannerDiscovery="false" value="Cortex-A78.AArch64.ARMv8.Neon.Crypto" valueType="string"/>
<targetPlatform id="com.arm.toolchain.v6.lib.debug.base.var.arm_compiler_6-6.1684503312.2127819066" name=""/>
@@ -105,9 +117,25 @@
</folderInfo>
+ <fileInfo id="com.arm.eclipse.build.config.v6.lib.debug.base.1470528944.214318543" name="tx_thread_timeout.c" rcbsApplicability="disable" resourcePath="src_generic/tx_thread_timeout.c" toolsToInvoke="com.arm.tool.c.compiler.v6.base.var.arm_compiler_6-6.2072709428.1899536638">
+
+ <tool id="com.arm.tool.c.compiler.v6.base.var.arm_compiler_6-6.2072709428.1899536638" name="Arm C Compiler 6" superClass="com.arm.tool.c.compiler.v6.base.var.arm_compiler_6-6.2072709428">
+
+ <inputType id="com.arm.tool.c.compiler.v6.base.input.1006773355" superClass="com.arm.tool.c.compiler.v6.base.input"/>
+
+ </tool>
+
+ </fileInfo>
+
+ <fileInfo id="com.arm.eclipse.build.config.v6.lib.debug.base.1470528944.1145515026" name="tx_misra.c" rcbsApplicability="disable" resourcePath="src_generic/tx_misra.c" toolsToInvoke="com.arm.tool.c.compiler.v6.base.var.arm_compiler_6-6.2072709428.1242981128">
+
+ <tool id="com.arm.tool.c.compiler.v6.base.var.arm_compiler_6-6.2072709428.1242981128" name="Arm C Compiler 6" superClass="com.arm.tool.c.compiler.v6.base.var.arm_compiler_6-6.2072709428"/>
+
+ </fileInfo>
+
<sourceEntries>
- <entry excluding="src_generic/tx_misra.c|src_generic/tx_thread_timeout.c" flags="VALUE_WORKSPACE_PATH|RESOLVED" kind="sourcePath" name=""/>
+ <entry flags="VALUE_WORKSPACE_PATH|RESOLVED" kind="sourcePath" name=""/>
</sourceEntries>
diff --git a/ports_smp/cortex_a78_smp/ac6/inc/tx_port.h b/ports_smp/cortex_a78_smp/ac6/inc/tx_port.h
index e97d78d5..38c86cb2 100644
--- a/ports_smp/cortex_a78_smp/ac6/inc/tx_port.h
+++ b/ports_smp/cortex_a78_smp/ac6/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_smp/cortex_a78_smp/ac6/src/tx_thread_context_restore.S b/ports_smp/cortex_a78_smp/ac6/src/tx_thread_context_restore.S
index e2c48868..5cd7a9df 100644
--- a/ports_smp/cortex_a78_smp/ac6/src/tx_thread_context_restore.S
+++ b/ports_smp/cortex_a78_smp/ac6/src/tx_thread_context_restore.S
@@ -19,10 +19,9 @@
/** */
/**************************************************************************/
/**************************************************************************/
-
-
-/* Include macros for modifying the wait list. */
-#include "tx_thread_smp_protection_wait_list_macros.h"
+#ifdef TX_INCLUDE_USER_DEFINE_FILE
+#include "tx_user.h"
+#endif
.text
.align 3
@@ -31,7 +30,7 @@
/* FUNCTION RELEASE */
/* */
/* _tx_thread_context_restore ARMv8-A-SMP */
-/* 6.1.10 */
+/* 6.3.0 */
/* AUTHOR */
/* */
/* William E. Lamie, Microsoft Corporation */
@@ -207,74 +206,6 @@ __tx_thread_no_preempt_restore:
// {
__tx_thread_preempt_restore:
- /* Was the thread being preempted waiting for the lock? */
- // if (_tx_thread_smp_protect_wait_counts[this_core] != 0)
- // {
-
- LDR x2, =_tx_thread_smp_protect_wait_counts // Load waiting count list
- LDR w3, [x2, x8, LSL #2] // Load waiting value for this core
- CMP w3, #0
- BEQ _nobody_waiting_for_lock // Is the core waiting for the lock?
-
- /* Do we not have the lock? This means the ISR never got the inter-core lock. */
- // if (_tx_thread_smp_protection.tx_thread_smp_protect_owned != this_core)
- // {
-
- LDR x2, =_tx_thread_smp_protection // Load address of protection structure
- LDR w3, [x2, #4] // Pickup the owning core
- CMP w8, w3 // Compare our core to the owning core
- BEQ _this_core_has_lock // Do we have the lock?
-
- /* We don't have the lock. This core should be in the list. Remove it. */
- // _tx_thread_smp_protect_wait_list_remove(this_core);
-
- _tx_thread_smp_protect_wait_list_remove // Call macro to remove core from the list
- B _nobody_waiting_for_lock // Leave
-
- // }
- // else
- // {
- /* We have the lock. This means the ISR got the inter-core lock, but
- never released it because it saw that there was someone waiting.
- Note this core is not in the list. */
-
-_this_core_has_lock:
-
- /* We're no longer waiting. Note that this should be zero since this happens during thread preemption. */
- // _tx_thread_smp_protect_wait_counts[core]--;
-
- LDR x2, =_tx_thread_smp_protect_wait_counts // Load waiting count list
- LDR w3, [x2, x8, LSL #2] // Load waiting value for this core
- SUB w3, w3, #1 // Decrement waiting value. Should be zero now
- STR w3, [x2, x8, LSL #2] // Store new waiting value
-
- /* Now release the inter-core lock. */
-
- /* Set protected core as invalid. */
- // _tx_thread_smp_protection.tx_thread_smp_protect_core = 0xFFFFFFFF;
-
- LDR x2, =_tx_thread_smp_protection // Load address of protection structure
- MOV w3, #0xFFFFFFFF // Build invalid value
- STR w3, [x2, #4] // Mark the protected core as invalid
- DMB ISH // Ensure that accesses to shared resource have completed
-
- /* Release protection. */
- // _tx_thread_smp_protection.tx_thread_smp_protect_in_force = 0;
-
- MOV w3, #0 // Build release protection value
- STR w3, [x2, #0] // Release the protection
- DSB ISH // To ensure update of the protection occurs before other CPUs awake
-
- /* Wake up waiting processors. Note interrupts are already enabled. */
-
-#ifdef TX_ENABLE_WFE
- SEV // Send event to other CPUs
-#endif
-
- // }
- // }
-
-_nobody_waiting_for_lock:
LDR x4, [x0, #8] // Switch to thread stack pointer
MOV sp, x4 //
@@ -348,6 +279,7 @@ __tx_thread_dont_save_ts:
/* Set bit indicating this thread is ready for execution. */
+ DMB ISH // Ensure that accesses to shared resource have completed
MOV x2, #1 // Build ready flag
STR w2, [x0, #260] // Set thread's ready flag
DMB ISH // Ensure that accesses to shared resource have completed
diff --git a/ports_smp/cortex_a78_smp/ac6/src/tx_thread_context_save.S b/ports_smp/cortex_a78_smp/ac6/src/tx_thread_context_save.S
index f43809f5..76641067 100644
--- a/ports_smp/cortex_a78_smp/ac6/src/tx_thread_context_save.S
+++ b/ports_smp/cortex_a78_smp/ac6/src/tx_thread_context_save.S
@@ -19,7 +19,9 @@
/** */
/**************************************************************************/
/**************************************************************************/
-
+#ifdef TX_INCLUDE_USER_DEFINE_FILE
+#include "tx_user.h"
+#endif
.text
.align 3
@@ -28,7 +30,7 @@
/* FUNCTION RELEASE */
/* */
/* _tx_thread_context_save ARMv8-A-SMP */
-/* 6.1.10 */
+/* 6.3.0 */
/* AUTHOR */
/* */
/* William E. Lamie, Microsoft Corporation */
diff --git a/ports_smp/cortex_a78_smp/ac6/src/tx_thread_interrupt_control.S b/ports_smp/cortex_a78_smp/ac6/src/tx_thread_interrupt_control.S
index d4235180..21ec2dd1 100644
--- a/ports_smp/cortex_a78_smp/ac6/src/tx_thread_interrupt_control.S
+++ b/ports_smp/cortex_a78_smp/ac6/src/tx_thread_interrupt_control.S
@@ -19,7 +19,9 @@
/** */
/**************************************************************************/
/**************************************************************************/
-
+#ifdef TX_INCLUDE_USER_DEFINE_FILE
+#include "tx_user.h"
+#endif
.text
.align 3
@@ -28,7 +30,7 @@
/* FUNCTION RELEASE */
/* */
/* _tx_thread_interrupt_control ARMv8-A */
-/* 6.1.10 */
+/* 6.3.0 */
/* AUTHOR */
/* */
/* William E. Lamie, Microsoft Corporation */
diff --git a/ports_smp/cortex_a78_smp/ac6/src/tx_thread_interrupt_disable.S b/ports_smp/cortex_a78_smp/ac6/src/tx_thread_interrupt_disable.S
index 08f0e7e1..af2ef874 100644
--- a/ports_smp/cortex_a78_smp/ac6/src/tx_thread_interrupt_disable.S
+++ b/ports_smp/cortex_a78_smp/ac6/src/tx_thread_interrupt_disable.S
@@ -19,7 +19,9 @@
/** */
/**************************************************************************/
/**************************************************************************/
-
+#ifdef TX_INCLUDE_USER_DEFINE_FILE
+#include "tx_user.h"
+#endif
.text
.align 3
@@ -28,7 +30,7 @@
/* FUNCTION RELEASE */
/* */
/* _tx_thread_interrupt_disable ARMv8-A */
-/* 6.1.10 */
+/* 6.3.0 */
/* AUTHOR */
/* */
/* William E. Lamie, Microsoft Corporation */
diff --git a/ports_smp/cortex_a78_smp/ac6/src/tx_thread_interrupt_restore.S b/ports_smp/cortex_a78_smp/ac6/src/tx_thread_interrupt_restore.S
index d0191c32..3e0780d0 100644
--- a/ports_smp/cortex_a78_smp/ac6/src/tx_thread_interrupt_restore.S
+++ b/ports_smp/cortex_a78_smp/ac6/src/tx_thread_interrupt_restore.S
@@ -19,7 +19,9 @@
/** */
/**************************************************************************/
/**************************************************************************/
-
+#ifdef TX_INCLUDE_USER_DEFINE_FILE
+#include "tx_user.h"
+#endif
.text
.align 3
@@ -27,8 +29,8 @@
/* */
/* FUNCTION RELEASE */
/* */
-/* _tx_thread_interrupt_restore ARMv8-A-SMP */
-/* 6.1.10 */
+/* _tx_thread_interrupt_restore ARMv8-A */
+/* 6.3.0 */
/* AUTHOR */
/* */
/* William E. Lamie, Microsoft Corporation */
diff --git a/ports_smp/cortex_a78_smp/ac6/src/tx_thread_schedule.S b/ports_smp/cortex_a78_smp/ac6/src/tx_thread_schedule.S
index 782491cc..de6b70dd 100644
--- a/ports_smp/cortex_a78_smp/ac6/src/tx_thread_schedule.S
+++ b/ports_smp/cortex_a78_smp/ac6/src/tx_thread_schedule.S
@@ -19,7 +19,9 @@
/** */
/**************************************************************************/
/**************************************************************************/
-
+#ifdef TX_INCLUDE_USER_DEFINE_FILE
+#include "tx_user.h"
+#endif
.text
.align 3
@@ -28,7 +30,7 @@
/* FUNCTION RELEASE */
/* */
/* _tx_thread_schedule ARMv8-A-SMP */
-/* 6.1.10 */
+/* 6.3.0 */
/* AUTHOR */
/* */
/* William E. Lamie, Microsoft Corporation */
@@ -156,7 +158,7 @@ _tx_thread_ready_for_execution:
LDR x2, =_tx_thread_current_ptr // Pickup address of current thread
STR x0, [x2, x20, LSL #3] // Setup current thread pointer
-
+ DMB ISH
LDR x1, [x1, x20, LSL #3] // Reload the execute pointer
CMP w0, w1 // Did it change?
BEQ _execute_pointer_did_not_change // If not, skip handling
diff --git a/ports_smp/cortex_a78_smp/ac6/src/tx_thread_smp_core_get.S b/ports_smp/cortex_a78_smp/ac6/src/tx_thread_smp_core_get.S
index 4ffb8cc6..ea14c901 100644
--- a/ports_smp/cortex_a78_smp/ac6/src/tx_thread_smp_core_get.S
+++ b/ports_smp/cortex_a78_smp/ac6/src/tx_thread_smp_core_get.S
@@ -19,7 +19,9 @@
/** */
/**************************************************************************/
/**************************************************************************/
-
+#ifdef TX_INCLUDE_USER_DEFINE_FILE
+#include "tx_user.h"
+#endif
.text
.align 3
@@ -27,8 +29,8 @@
/* */
/* FUNCTION RELEASE */
/* */
-/* _tx_thread_smp_core_get Cortex-A35-SMP/AC6 */
-/* 6.1.10 */
+/* _tx_thread_smp_core_get ARMv8-A-SMP */
+/* 6.3.0 */
/* AUTHOR */
/* */
/* William E. Lamie, Microsoft Corporation */
diff --git a/ports_smp/cortex_a78_smp/ac6/src/tx_thread_smp_core_preempt.S b/ports_smp/cortex_a78_smp/ac6/src/tx_thread_smp_core_preempt.S
index 8dc6933c..1d28907f 100644
--- a/ports_smp/cortex_a78_smp/ac6/src/tx_thread_smp_core_preempt.S
+++ b/ports_smp/cortex_a78_smp/ac6/src/tx_thread_smp_core_preempt.S
@@ -19,6 +19,11 @@
/** */
/**************************************************************************/
/**************************************************************************/
+#ifdef TX_INCLUDE_USER_DEFINE_FILE
+#include "tx_user.h"
+#endif
+
+#define ICC_SGI1R_EL1 S3_0_C12_C11_5
.text
@@ -27,8 +32,8 @@
/* */
/* FUNCTION RELEASE */
/* */
-/* _tx_thread_smp_core_preempt Cortex-A35-SMP/AC6 */
-/* 6.1.10 */
+/* _tx_thread_smp_core_preempt ARMv8-A-SMP */
+/* 6.3.0 */
/* AUTHOR */
/* */
/* William E. Lamie, Microsoft Corporation */
diff --git a/ports_smp/cortex_a78_smp/ac6/src/tx_thread_smp_current_state_get.S b/ports_smp/cortex_a78_smp/ac6/src/tx_thread_smp_current_state_get.S
index edae94d5..707b41d2 100644
--- a/ports_smp/cortex_a78_smp/ac6/src/tx_thread_smp_current_state_get.S
+++ b/ports_smp/cortex_a78_smp/ac6/src/tx_thread_smp_current_state_get.S
@@ -19,7 +19,9 @@
/** */
/**************************************************************************/
/**************************************************************************/
-
+#ifdef TX_INCLUDE_USER_DEFINE_FILE
+#include "tx_user.h"
+#endif
.text
.align 3
@@ -27,8 +29,8 @@
/* */
/* FUNCTION RELEASE */
/* */
-/* _tx_thread_smp_current_state_get Cortex-A35-SMP/AC6 */
-/* 6.1.10 */
+/* _tx_thread_smp_current_state_get ARMv8-A-SMP */
+/* 6.3.0 */
/* AUTHOR */
/* */
/* William E. Lamie, Microsoft Corporation */
diff --git a/ports_smp/cortex_a78_smp/ac6/src/tx_thread_smp_current_thread_get.S b/ports_smp/cortex_a78_smp/ac6/src/tx_thread_smp_current_thread_get.S
index dd740e05..6c4bc9af 100644
--- a/ports_smp/cortex_a78_smp/ac6/src/tx_thread_smp_current_thread_get.S
+++ b/ports_smp/cortex_a78_smp/ac6/src/tx_thread_smp_current_thread_get.S
@@ -19,7 +19,9 @@
/** */
/**************************************************************************/
/**************************************************************************/
-
+#ifdef TX_INCLUDE_USER_DEFINE_FILE
+#include "tx_user.h"
+#endif
.text
.align 3
@@ -27,8 +29,8 @@
/* */
/* FUNCTION RELEASE */
/* */
-/* _tx_thread_smp_current_thread_get Cortex-A35-SMP/AC6 */
-/* 6.1.10 */
+/* _tx_thread_smp_current_thread_get ARMv8-A-SMP */
+/* 6.3.0 */
/* AUTHOR */
/* */
/* William E. Lamie, Microsoft Corporation */
diff --git a/ports_smp/cortex_a78_smp/ac6/src/tx_thread_smp_initialize_wait.S b/ports_smp/cortex_a78_smp/ac6/src/tx_thread_smp_initialize_wait.S
index 985136b5..defd791c 100644
--- a/ports_smp/cortex_a78_smp/ac6/src/tx_thread_smp_initialize_wait.S
+++ b/ports_smp/cortex_a78_smp/ac6/src/tx_thread_smp_initialize_wait.S
@@ -19,7 +19,9 @@
/** */
/**************************************************************************/
/**************************************************************************/
-
+#ifdef TX_INCLUDE_USER_DEFINE_FILE
+#include "tx_user.h"
+#endif
.text
.align 3
@@ -27,8 +29,8 @@
/* */
/* FUNCTION RELEASE */
/* */
-/* _tx_thread_smp_initialize_wait Cortex-A35-SMP/AC6 */
-/* 6.1.10 */
+/* _tx_thread_smp_initialize_wait ARMv8-A-SMP */
+/* 6.3.0 */
/* AUTHOR */
/* */
/* William E. Lamie, Microsoft Corporation */
diff --git a/ports_smp/cortex_a78_smp/ac6/src/tx_thread_smp_low_level_initialize.S b/ports_smp/cortex_a78_smp/ac6/src/tx_thread_smp_low_level_initialize.S
index 64b854d0..99b20d24 100644
--- a/ports_smp/cortex_a78_smp/ac6/src/tx_thread_smp_low_level_initialize.S
+++ b/ports_smp/cortex_a78_smp/ac6/src/tx_thread_smp_low_level_initialize.S
@@ -19,7 +19,9 @@
/** */
/**************************************************************************/
/**************************************************************************/
-
+#ifdef TX_INCLUDE_USER_DEFINE_FILE
+#include "tx_user.h"
+#endif
.text
.align 3
@@ -27,8 +29,8 @@
/* */
/* FUNCTION RELEASE */
/* */
-/* _tx_thread_smp_low_level_initialize Cortex-A35-SMP/AC6 */
-/* 6.1.10 */
+/* _tx_thread_smp_low_level_initialize ARMv8-A-SMP */
+/* 6.3.0 */
/* AUTHOR */
/* */
/* William E. Lamie, Microsoft Corporation */
diff --git a/ports_smp/cortex_a78_smp/ac6/src/tx_thread_smp_protect.S b/ports_smp/cortex_a78_smp/ac6/src/tx_thread_smp_protect.S
index 30a43701..1155a3fa 100644
--- a/ports_smp/cortex_a78_smp/ac6/src/tx_thread_smp_protect.S
+++ b/ports_smp/cortex_a78_smp/ac6/src/tx_thread_smp_protect.S
@@ -19,7 +19,9 @@
/** */
/**************************************************************************/
/**************************************************************************/
-
+#ifdef TX_INCLUDE_USER_DEFINE_FILE
+#include "tx_user.h"
+#endif
/* Include macros for modifying the wait list. */
#include "tx_thread_smp_protection_wait_list_macros.h"
@@ -31,8 +33,8 @@
/* */
/* FUNCTION RELEASE */
/* */
-/* _tx_thread_smp_protect Cortex-A35-SMP/AC6 */
-/* 6.1.10 */
+/* _tx_thread_smp_protect ARMv8-A-SMP */
+/* 6.3.0 */
/* AUTHOR */
/* */
/* William E. Lamie, Microsoft Corporation */
@@ -71,293 +73,49 @@ _tx_thread_smp_protect:
/* Pickup the CPU ID. */
- MRS x1, MPIDR_EL1 // Pickup the core ID
+ MRS x2, MPIDR_EL1 // Pickup the core ID
#ifdef TX_ARMV8_2
#if TX_THREAD_SMP_CLUSTERS > 1
- UBFX x7, x1, #16, #8 // Isolate cluster ID
+ UBFX x7, x2, #16, #8 // Isolate cluster ID
#endif
- UBFX x1, x1, #8, #8 // Isolate core ID
+ UBFX x2, x2, #8, #8 // Isolate core ID
#else
#if TX_THREAD_SMP_CLUSTERS > 1
- UBFX x7, x1, #8, #8 // Isolate cluster ID
+ UBFX x7, x2, #8, #8 // Isolate cluster ID
#endif
- UBFX x1, x1, #0, #8 // Isolate core ID
+ UBFX x2, x2, #0, #8 // Isolate core ID
#endif
#if TX_THREAD_SMP_CLUSTERS > 1
- ADDS x1, x1, x7, LSL #2 // Calculate CPU ID
+ ADDS x2, x2, x7, LSL #2 // Calculate CPU ID
#endif
- /* Do we already have protection? */
- // if (this_core == _tx_thread_smp_protection.tx_thread_smp_protect_core)
- // {
-
- LDR x2, =_tx_thread_smp_protection // Build address to protection structure
- LDR w3, [x2, #4] // Pickup the owning core
- CMP w1, w3 // Is it not this core?
- BNE _protection_not_owned // No, the protection is not already owned
-
- /* We already have protection. */
-
- /* Increment the protection count. */
- // _tx_thread_smp_protection.tx_thread_smp_protect_count++;
-
- LDR w3, [x2, #8] // Pickup ownership count
- ADD w3, w3, #1 // Increment ownership count
- STR w3, [x2, #8] // Store ownership count
- DMB ISH
-
- B _return
-
-_protection_not_owned:
-
- /* Is the lock available? */
- // if (_tx_thread_smp_protection.tx_thread_smp_protect_in_force == 0)
- // {
-
- LDAXR w3, [x2, #0] // Pickup the protection flag
- CMP w3, #0
- BNE _start_waiting // No, protection not available
-
- /* Is the list empty? */
- // if (_tx_thread_smp_protect_wait_list_head == _tx_thread_smp_protect_wait_list_tail)
- // {
-
- LDR x3, =_tx_thread_smp_protect_wait_list_head
- LDR w3, [x3]
- LDR x4, =_tx_thread_smp_protect_wait_list_tail
- LDR w4, [x4]
- CMP w3, w4
- BNE _list_not_empty
-
- /* Try to get the lock. */
- // if (write_exclusive(&_tx_thread_smp_protection.tx_thread_smp_protect_in_force, 1) == SUCCESS)
- // {
-
- MOV w3, #1 // Build lock value
- STXR w4, w3, [x2, #0] // Attempt to get the protection
- CMP w4, #0
- BNE _start_waiting // Did it fail?
-
- /* We got the lock! */
- // _tx_thread_smp_protect_lock_got();
-
- DMB ISH // Ensure write to protection finishes
- _tx_thread_smp_protect_lock_got // Call the lock got function
-
- B _return
-
-_list_not_empty:
-
- /* Are we at the front of the list? */
- // if (this_core == _tx_thread_smp_protect_wait_list[_tx_thread_smp_protect_wait_list_head])
- // {
-
- LDR x3, =_tx_thread_smp_protect_wait_list_head // Get the address of the head
- LDR w3, [x3] // Get the value of the head
- LDR x4, =_tx_thread_smp_protect_wait_list // Get the address of the list
- LDR w4, [x4, x3, LSL #2] // Get the value at the head index
-
- CMP w1, w4
- BNE _start_waiting
-
- /* Is the lock still available? */
- // if (_tx_thread_smp_protection.tx_thread_smp_protect_in_force == 0)
- // {
-
- LDAXR w3, [x2, #0] // Pickup the protection flag
- CMP w3, #0
- BNE _start_waiting // No, protection not available
-
- /* Get the lock. */
- // _tx_thread_smp_protection.tx_thread_smp_protect_in_force = 1;
-
- MOV w3, #1 // Build lock value
- STXR w4, w3, [x2, #0] // Attempt to get the protection
- CMP w4, #0
- BNE _start_waiting // Did it fail?
- DMB ISH //
-
- /* Got the lock. */
- // _tx_thread_smp_protect_lock_got();
-
- _tx_thread_smp_protect_lock_got
-
- /* Remove this core from the wait list. */
- // _tx_thread_smp_protect_remove_from_front_of_list();
-
- _tx_thread_smp_protect_remove_from_front_of_list
-
- B _return
-
-_start_waiting:
-
- /* For one reason or another, we didn't get the lock. */
-
- /* Increment wait count. */
- // _tx_thread_smp_protect_wait_counts[this_core]++;
-
- LDR x3, =_tx_thread_smp_protect_wait_counts // Load wait list counts
- LDR w4, [x3, x1, LSL #2] // Load waiting value for this core
- ADD w4, w4, #1 // Increment wait value
- STR w4, [x3, x1, LSL #2] // Store new wait value
-
- /* Have we not added ourselves to the list yet? */
- // if (_tx_thread_smp_protect_wait_counts[this_core] == 1)
- // {
-
- CMP w4, #1
- BNE _already_in_list0 // Is this core already waiting?
-
- /* Add ourselves to the list. */
- // _tx_thread_smp_protect_wait_list_add(this_core);
-
- _tx_thread_smp_protect_wait_list_add // Call macro to add ourselves to the list
-
- // }
-
-_already_in_list0:
-
- /* Restore interrupts. */
+ LDR x1, =_tx_thread_smp_protection // Build address to protection structure
+ LDR w3, [x1, #4] // Pickup the owning core
+ CMP w3, w2 // Is it this core?
+ BEQ _owned // Yes, the protection is already owned
+ LDAXR w4, [x1, #0] // Pickup the protection flag
+ CBZ w4, _get_protection // Yes, get the protection
MSR DAIF, x0 // Restore interrupts
ISB //
#ifdef TX_ENABLE_WFE
WFE // Go into standby
#endif
+ B _tx_thread_smp_protect // On waking, restart the protection attempt
- /* We do this until we have the lock. */
- // while (1)
- // {
-
-_try_to_get_lock:
-
- /* Disable interrupts so we don't get preempted. */
-
- MRS x0, DAIF // Pickup current interrupt posture
- MSR DAIFSet, 0x3 // Lockout interrupts
-
- /* Pickup the CPU ID. */
-
- MRS x1, MPIDR_EL1 // Pickup the core ID
-#ifdef TX_ARMV8_2
-#if TX_THREAD_SMP_CLUSTERS > 1
- UBFX x7, x1, #16, #8 // Isolate cluster ID
-#endif
- UBFX x1, x1, #8, #8 // Isolate core ID
-#else
-#if TX_THREAD_SMP_CLUSTERS > 1
- UBFX x7, x1, #8, #8 // Isolate cluster ID
-#endif
- UBFX x1, x1, #0, #8 // Isolate core ID
-#endif
-#if TX_THREAD_SMP_CLUSTERS > 1
- ADDS x1, x1, x7, LSL #2 // Calculate CPU ID
-#endif
-
- /* Do we already have protection? */
- // if (this_core == _tx_thread_smp_protection.tx_thread_smp_protect_core)
- // {
-
- LDR w3, [x2, #4] // Pickup the owning core
- CMP w3, w1 // Is it this core?
- BEQ _got_lock_after_waiting // Yes, the protection is already owned. This means
- // an ISR preempted us and got protection
-
- // }
-
- /* Are we at the front of the list? */
- // if (this_core == _tx_thread_smp_protect_wait_list[_tx_thread_smp_protect_wait_list_head])
- // {
-
- LDR x3, =_tx_thread_smp_protect_wait_list_head // Get the address of the head
- LDR w3, [x3] // Get the value of the head
- LDR x4, =_tx_thread_smp_protect_wait_list // Get the address of the list
- LDR w4, [x4, x3, LSL #2] // Get the value at the head index
-
- CMP w1, w4
- BNE _did_not_get_lock
-
- /* Is the lock still available? */
- // if (_tx_thread_smp_protection.tx_thread_smp_protect_in_force == 0)
- // {
-
- LDAXR w3, [x2, #0] // Pickup the protection flag
- CMP w3, #0
- BNE _did_not_get_lock // No, protection not available
-
- /* Get the lock. */
- // _tx_thread_smp_protection.tx_thread_smp_protect_in_force = 1;
-
- MOV w3, #1 // Build lock value
- STXR w4, w3, [x2, #0] // Attempt to get the protection
- CMP w4, #0
- BNE _did_not_get_lock // Did it fail?
- DMB ISH //
-
- /* Got the lock. */
- // _tx_thread_smp_protect_lock_got();
-
- _tx_thread_smp_protect_lock_got
-
- /* Remove this core from the wait list. */
- // _tx_thread_smp_protect_remove_from_front_of_list();
-
- _tx_thread_smp_protect_remove_from_front_of_list
-
- B _got_lock_after_waiting
-
-_did_not_get_lock:
-
- /* For one reason or another, we didn't get the lock. */
-
- /* Were we removed from the list? This can happen if we're a thread
- and we got preempted. */
- // if (_tx_thread_smp_protect_wait_counts[this_core] == 0)
- // {
-
- LDR x3, =_tx_thread_smp_protect_wait_counts // Load wait list counts
- LDR w4, [x3, x1, LSL #2] // Load waiting value for this core
- CMP w4, #0
- BNE _already_in_list1 // Is this core already in the list?
-
- /* Add ourselves to the list. */
- // _tx_thread_smp_protect_wait_list_add(this_core);
-
- _tx_thread_smp_protect_wait_list_add // Call macro to add ourselves to the list
-
- /* Our waiting count was also reset when we were preempted. Increment it again. */
- // _tx_thread_smp_protect_wait_counts[this_core]++;
-
- LDR x3, =_tx_thread_smp_protect_wait_counts // Load wait list counts
- LDR w4, [x3, x1, LSL #2] // Load waiting value for this core
- ADD w4, w4, #1 // Increment wait value
- STR w4, [x3, x1, LSL #2] // Store new wait value value
-
- // }
-
-_already_in_list1:
-
- /* Restore interrupts and try again. */
-
+_get_protection:
+ MOV x4, #1 // Build lock value
+ STXR w5, w4, [x1] // Attempt to get the protection
+ CBZ w5, _got_protection // Did it succeed? w5 = 0 means success!
MSR DAIF, x0 // Restore interrupts
- ISB //
-#ifdef TX_ENABLE_WFE
- WFE // Go into standby
-#endif
- B _try_to_get_lock // On waking, restart the protection attempt
-
-_got_lock_after_waiting:
-
- /* We're no longer waiting. */
- // _tx_thread_smp_protect_wait_counts[this_core]--;
-
- LDR x3, =_tx_thread_smp_protect_wait_counts // Load waiting list
- LDR w4, [x3, x1, LSL #2] // Load current wait value
- SUB w4, w4, #1 // Decrement wait value
- STR w4, [x3, x1, LSL #2] // Store new wait value value
-
- /* Restore registers and return. */
-
-_return:
+ B _tx_thread_smp_protect // Restart the protection attempt
+_got_protection:
+ DMB ISH //
+ STR w2, [x1, #4] // Save owning core
+_owned:
+ LDR w5, [x1, #8] // Pickup ownership count
+ ADD w5, w5, #1 // Increment ownership count
+ STR w5, [x1, #8] // Store ownership count
+ DMB ISH //
RET
diff --git a/ports_smp/cortex_a78_smp/ac6/src/tx_thread_smp_time_get.S b/ports_smp/cortex_a78_smp/ac6/src/tx_thread_smp_time_get.S
index f3045738..4bb9f1cb 100644
--- a/ports_smp/cortex_a78_smp/ac6/src/tx_thread_smp_time_get.S
+++ b/ports_smp/cortex_a78_smp/ac6/src/tx_thread_smp_time_get.S
@@ -9,6 +9,7 @@
* SPDX-License-Identifier: MIT
**************************************************************************/
+// Portions of this file were generated with AI assistance.
/**************************************************************************/
/**************************************************************************/
@@ -19,7 +20,9 @@
/** */
/**************************************************************************/
/**************************************************************************/
-
+#ifdef TX_INCLUDE_USER_DEFINE_FILE
+#include "tx_user.h"
+#endif
.text
.align 3
@@ -27,8 +30,8 @@
/* */
/* FUNCTION RELEASE */
/* */
-/* _tx_thread_smp_time_get Cortex-A35-SMP/AC6 */
-/* 6.1.10 */
+/* _tx_thread_smp_time_get ARMv8-A-SMP */
+/* 6.3.0 */
/* AUTHOR */
/* */
/* William E. Lamie, Microsoft Corporation */
@@ -58,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_smp/cortex_a78_smp/ac6/src/tx_thread_smp_unprotect.S b/ports_smp/cortex_a78_smp/ac6/src/tx_thread_smp_unprotect.S
index 49af176a..680e8bc8 100644
--- a/ports_smp/cortex_a78_smp/ac6/src/tx_thread_smp_unprotect.S
+++ b/ports_smp/cortex_a78_smp/ac6/src/tx_thread_smp_unprotect.S
@@ -19,7 +19,9 @@
/** */
/**************************************************************************/
/**************************************************************************/
-
+#ifdef TX_INCLUDE_USER_DEFINE_FILE
+#include "tx_user.h"
+#endif
.text
.align 3
@@ -27,8 +29,8 @@
/* */
/* FUNCTION RELEASE */
/* */
-/* _tx_thread_smp_unprotect Cortex-A35-SMP/AC6 */
-/* 6.1.10 */
+/* _tx_thread_smp_unprotect ARMv8-A-SMP */
+/* 6.3.0 */
/* AUTHOR */
/* */
/* William E. Lamie, Microsoft Corporation */
@@ -96,11 +98,6 @@ _tx_thread_smp_unprotect:
CMP w3, #0 // Is the preempt disable flag set?
BNE _still_protected // Yes, skip the protection release
- LDR x2,=_tx_thread_smp_protect_wait_counts // Build build address of wait counts
- LDR w3, [x2, x1, LSL #2] // Pickup wait list value
- CMP w3, #0 // Are any entities on this core waiting?
- BNE _still_protected // Yes, skip the protection release
-
LDR x2,=_tx_thread_smp_protection // Build address of protection structure
MOV w3, #0xFFFFFFFF // Build invalid value
STR w3, [x2, #4] // Mark the protected core as invalid
diff --git a/ports_smp/cortex_a78_smp/ac6/src/tx_thread_stack_build.S b/ports_smp/cortex_a78_smp/ac6/src/tx_thread_stack_build.S
index fa11a65c..581e259e 100644
--- a/ports_smp/cortex_a78_smp/ac6/src/tx_thread_stack_build.S
+++ b/ports_smp/cortex_a78_smp/ac6/src/tx_thread_stack_build.S
@@ -19,7 +19,9 @@
/** */
/**************************************************************************/
/**************************************************************************/
-
+#ifdef TX_INCLUDE_USER_DEFINE_FILE
+#include "tx_user.h"
+#endif
.text
.align 3
@@ -28,7 +30,7 @@
/* FUNCTION RELEASE */
/* */
/* _tx_thread_stack_build ARMv8-A-SMP */
-/* 6.1.10 */
+/* 6.3.0 */
/* AUTHOR */
/* */
/* William E. Lamie, Microsoft Corporation */
diff --git a/ports_smp/cortex_a78_smp/ac6/src/tx_thread_system_return.S b/ports_smp/cortex_a78_smp/ac6/src/tx_thread_system_return.S
index 4eebb9aa..23c75241 100644
--- a/ports_smp/cortex_a78_smp/ac6/src/tx_thread_system_return.S
+++ b/ports_smp/cortex_a78_smp/ac6/src/tx_thread_system_return.S
@@ -19,7 +19,9 @@
/** */
/**************************************************************************/
/**************************************************************************/
-
+#ifdef TX_INCLUDE_USER_DEFINE_FILE
+#include "tx_user.h"
+#endif
.text
.align 3
@@ -28,7 +30,7 @@
/* FUNCTION RELEASE */
/* */
/* _tx_thread_system_return ARMv8-A-SMP */
-/* 6.1.10 */
+/* 6.3.0 */
/* AUTHOR */
/* */
/* William E. Lamie, Microsoft Corporation */
@@ -159,6 +161,7 @@ __tx_thread_dont_save_ts:
/* Set ready bit in thread control block. */
+ DMB ISH // Ensure that accesses to shared resource have completed
MOV x3, #1 // Build ready value
STR w3, [x6, #260] // Make the thread ready
DMB ISH //
diff --git a/ports_smp/cortex_a78_smp/ac6/src/tx_timer_interrupt.S b/ports_smp/cortex_a78_smp/ac6/src/tx_timer_interrupt.S
index 6f90e5d1..5c6a6bc2 100644
--- a/ports_smp/cortex_a78_smp/ac6/src/tx_timer_interrupt.S
+++ b/ports_smp/cortex_a78_smp/ac6/src/tx_timer_interrupt.S
@@ -19,7 +19,9 @@
/** */
/**************************************************************************/
/**************************************************************************/
-
+#ifdef TX_INCLUDE_USER_DEFINE_FILE
+#include "tx_user.h"
+#endif
.text
.align 3
@@ -28,7 +30,7 @@
/* FUNCTION RELEASE */
/* */
/* _tx_timer_interrupt ARMv8-A-SMP */
-/* 6.1.10 */
+/* 6.3.0 */
/* AUTHOR */
/* */
/* William E. Lamie, Microsoft Corporation */
diff --git a/ports_smp/cortex_a78_smp/gnu/CMakeLists.txt b/ports_smp/cortex_a78_smp/gnu/CMakeLists.txt
new file mode 100644
index 00000000..36f7492b
--- /dev/null
+++ b/ports_smp/cortex_a78_smp/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_smp/cortex_a78_smp/gnu/example_build/build_threadx.sh b/ports_smp/cortex_a78_smp/gnu/example_build/build_threadx.sh
new file mode 100755
index 00000000..b3b2cd36
--- /dev/null
+++ b/ports_smp/cortex_a78_smp/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_smp/cortex_a78_smp/gnu/example_build/build_threadx_sample.sh b/ports_smp/cortex_a78_smp/gnu/example_build/build_threadx_sample.sh
new file mode 100755
index 00000000..94248a88
--- /dev/null
+++ b/ports_smp/cortex_a78_smp/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_smp/cortex_a78_smp/gnu/example_build/readme.md b/ports_smp/cortex_a78_smp/gnu/example_build/readme.md
new file mode 100644
index 00000000..3c52a7da
--- /dev/null
+++ b/ports_smp/cortex_a78_smp/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_smp/cortex_a78_smp/gnu/example_build/sample_threadx/sample_threadx.launch b/ports_smp/cortex_a78_smp/gnu/example_build/sample_threadx/sample_threadx.launch
index d583631e..baa98e1c 100644
--- a/ports_smp/cortex_a78_smp/gnu/example_build/sample_threadx/sample_threadx.launch
+++ b/ports_smp/cortex_a78_smp/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"/>
@@ -345,13 +338,13 @@
<listAttribute key="com.arm.debugger.views.common.AddressTracker.debugger.view.DisassemblyView.ranges">
<listEntry value="100"/>
</listAttribute>
- <stringAttribute key="config_db_activity_name" value="Cortex-A35x4 SMP"/>
+ <stringAttribute key="config_db_activity_name" value="Cortex-A78x4 SMP"/>
<stringAttribute key="config_db_connection_keys" value="dtsl_config dtsl_tracecapture_option connect_existing_model dtsl_config_script model_params model_iris config_file model_connection_address setup TCP_KILL_ON_EXIT TCP_DISABLE_EXTENDED_MODE"/>
<stringAttribute key="config_db_connection_type" value="Bare Metal Debug"/>
- <stringAttribute key="config_db_platform_name" value="Arm FVP - Base_A35x4"/>
+ <stringAttribute key="config_db_platform_name" value="Arm FVP - Base_A78x4"/>
<stringAttribute key="config_db_project_type" value="Bare Metal Debug"/>
<stringAttribute key="config_db_project_type_id" value="BARE_METAL"/>
- <stringAttribute key="config_db_taxonomy_id" value="/platform/armfvp/base_a35x4"/>
+ <stringAttribute key="config_db_taxonomy_id" value="/platform/armfvp/base_a78x4"/>
<stringAttribute key="config_file" value="CDB://iris_config.xml"/>
<booleanAttribute key="connectOnly" value="false"/>
<stringAttribute key="connect_existing_model" value="false"/>
@@ -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;"/>
+ <listEntry value="&quot;FVP_Base_Cortex-A78x4&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_smp/cortex_a78_smp/gnu/example_build/sample_threadx/semihost_stub.S b/ports_smp/cortex_a78_smp/gnu/example_build/sample_threadx/semihost_stub.S
new file mode 100644
index 00000000..c456875d
--- /dev/null
+++ b/ports_smp/cortex_a78_smp/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_smp/cortex_a78_smp/gnu/example_build/tx/.cproject b/ports_smp/cortex_a78_smp/gnu/example_build/tx/.cproject
index 11d7c2fe..e3f31405 100644
--- a/ports_smp/cortex_a78_smp/gnu/example_build/tx/.cproject
+++ b/ports_smp/cortex_a78_smp/gnu/example_build/tx/.cproject
@@ -129,9 +129,15 @@
</folderInfo>
+ <fileInfo id="com.arm.eclipse.cdt.managedbuild.ds5.gcc.baremetal.config.exe.debug.var.gcc-8.3.0-aarch64-elf.794347674.1482422597" name="tx_misra.c" rcbsApplicability="disable" resourcePath="src_generic/tx_misra.c" toolsToInvoke="com.arm.eclipse.cdt.managedbuild.ds5.gcc.baremetal.tool.c.compiler.var.gcc-8.3.0-aarch64-elf.1247168701.1451532610">
+
+ <tool id="com.arm.eclipse.cdt.managedbuild.ds5.gcc.baremetal.tool.c.compiler.var.gcc-8.3.0-aarch64-elf.1247168701.1451532610" name="GCC C Compiler 8.3.0 [aarch64-elf]" superClass="com.arm.eclipse.cdt.managedbuild.ds5.gcc.baremetal.tool.c.compiler.var.gcc-8.3.0-aarch64-elf.1247168701"/>
+
+ </fileInfo>
+
<sourceEntries>
- <entry excluding="src_generic/tx_misra.c|src_generic/tx_thread_timeout.c" flags="VALUE_WORKSPACE_PATH|RESOLVED" kind="sourcePath" name=""/>
+ <entry flags="VALUE_WORKSPACE_PATH|RESOLVED" kind="sourcePath" name=""/>
</sourceEntries>
diff --git a/ports_smp/cortex_a78_smp/gnu/inc/tx_port.h b/ports_smp/cortex_a78_smp/gnu/inc/tx_port.h
index e97d78d5..38c86cb2 100644
--- a/ports_smp/cortex_a78_smp/gnu/inc/tx_port.h
+++ b/ports_smp/cortex_a78_smp/gnu/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_smp/cortex_a78_smp/gnu/src/tx_initialize_low_level.S b/ports_smp/cortex_a78_smp/gnu/src/tx_initialize_low_level.S
index 43d87225..efb08b80 100644
--- a/ports_smp/cortex_a78_smp/gnu/src/tx_initialize_low_level.S
+++ b/ports_smp/cortex_a78_smp/gnu/src/tx_initialize_low_level.S
@@ -19,7 +19,9 @@
/** */
/**************************************************************************/
/**************************************************************************/
-
+#ifdef TX_INCLUDE_USER_DEFINE_FILE
+#include "tx_user.h"
+#endif
.text
.align 3
@@ -28,7 +30,7 @@
/* FUNCTION RELEASE */
/* */
/* _tx_initialize_low_level ARMv8-A-SMP */
-/* 6.1.10 */
+/* 6.3.0 */
/* AUTHOR */
/* */
/* William E. Lamie, Microsoft Corporation */
diff --git a/ports_smp/cortex_a78_smp/gnu/src/tx_thread_context_restore.S b/ports_smp/cortex_a78_smp/gnu/src/tx_thread_context_restore.S
index e2c48868..5cd7a9df 100644
--- a/ports_smp/cortex_a78_smp/gnu/src/tx_thread_context_restore.S
+++ b/ports_smp/cortex_a78_smp/gnu/src/tx_thread_context_restore.S
@@ -19,10 +19,9 @@
/** */
/**************************************************************************/
/**************************************************************************/
-
-
-/* Include macros for modifying the wait list. */
-#include "tx_thread_smp_protection_wait_list_macros.h"
+#ifdef TX_INCLUDE_USER_DEFINE_FILE
+#include "tx_user.h"
+#endif
.text
.align 3
@@ -31,7 +30,7 @@
/* FUNCTION RELEASE */
/* */
/* _tx_thread_context_restore ARMv8-A-SMP */
-/* 6.1.10 */
+/* 6.3.0 */
/* AUTHOR */
/* */
/* William E. Lamie, Microsoft Corporation */
@@ -207,74 +206,6 @@ __tx_thread_no_preempt_restore:
// {
__tx_thread_preempt_restore:
- /* Was the thread being preempted waiting for the lock? */
- // if (_tx_thread_smp_protect_wait_counts[this_core] != 0)
- // {
-
- LDR x2, =_tx_thread_smp_protect_wait_counts // Load waiting count list
- LDR w3, [x2, x8, LSL #2] // Load waiting value for this core
- CMP w3, #0
- BEQ _nobody_waiting_for_lock // Is the core waiting for the lock?
-
- /* Do we not have the lock? This means the ISR never got the inter-core lock. */
- // if (_tx_thread_smp_protection.tx_thread_smp_protect_owned != this_core)
- // {
-
- LDR x2, =_tx_thread_smp_protection // Load address of protection structure
- LDR w3, [x2, #4] // Pickup the owning core
- CMP w8, w3 // Compare our core to the owning core
- BEQ _this_core_has_lock // Do we have the lock?
-
- /* We don't have the lock. This core should be in the list. Remove it. */
- // _tx_thread_smp_protect_wait_list_remove(this_core);
-
- _tx_thread_smp_protect_wait_list_remove // Call macro to remove core from the list
- B _nobody_waiting_for_lock // Leave
-
- // }
- // else
- // {
- /* We have the lock. This means the ISR got the inter-core lock, but
- never released it because it saw that there was someone waiting.
- Note this core is not in the list. */
-
-_this_core_has_lock:
-
- /* We're no longer waiting. Note that this should be zero since this happens during thread preemption. */
- // _tx_thread_smp_protect_wait_counts[core]--;
-
- LDR x2, =_tx_thread_smp_protect_wait_counts // Load waiting count list
- LDR w3, [x2, x8, LSL #2] // Load waiting value for this core
- SUB w3, w3, #1 // Decrement waiting value. Should be zero now
- STR w3, [x2, x8, LSL #2] // Store new waiting value
-
- /* Now release the inter-core lock. */
-
- /* Set protected core as invalid. */
- // _tx_thread_smp_protection.tx_thread_smp_protect_core = 0xFFFFFFFF;
-
- LDR x2, =_tx_thread_smp_protection // Load address of protection structure
- MOV w3, #0xFFFFFFFF // Build invalid value
- STR w3, [x2, #4] // Mark the protected core as invalid
- DMB ISH // Ensure that accesses to shared resource have completed
-
- /* Release protection. */
- // _tx_thread_smp_protection.tx_thread_smp_protect_in_force = 0;
-
- MOV w3, #0 // Build release protection value
- STR w3, [x2, #0] // Release the protection
- DSB ISH // To ensure update of the protection occurs before other CPUs awake
-
- /* Wake up waiting processors. Note interrupts are already enabled. */
-
-#ifdef TX_ENABLE_WFE
- SEV // Send event to other CPUs
-#endif
-
- // }
- // }
-
-_nobody_waiting_for_lock:
LDR x4, [x0, #8] // Switch to thread stack pointer
MOV sp, x4 //
@@ -348,6 +279,7 @@ __tx_thread_dont_save_ts:
/* Set bit indicating this thread is ready for execution. */
+ DMB ISH // Ensure that accesses to shared resource have completed
MOV x2, #1 // Build ready flag
STR w2, [x0, #260] // Set thread's ready flag
DMB ISH // Ensure that accesses to shared resource have completed
diff --git a/ports_smp/cortex_a78_smp/gnu/src/tx_thread_context_save.S b/ports_smp/cortex_a78_smp/gnu/src/tx_thread_context_save.S
index f43809f5..76641067 100644
--- a/ports_smp/cortex_a78_smp/gnu/src/tx_thread_context_save.S
+++ b/ports_smp/cortex_a78_smp/gnu/src/tx_thread_context_save.S
@@ -19,7 +19,9 @@
/** */
/**************************************************************************/
/**************************************************************************/
-
+#ifdef TX_INCLUDE_USER_DEFINE_FILE
+#include "tx_user.h"
+#endif
.text
.align 3
@@ -28,7 +30,7 @@
/* FUNCTION RELEASE */
/* */
/* _tx_thread_context_save ARMv8-A-SMP */
-/* 6.1.10 */
+/* 6.3.0 */
/* AUTHOR */
/* */
/* William E. Lamie, Microsoft Corporation */
diff --git a/ports_smp/cortex_a78_smp/gnu/src/tx_thread_interrupt_control.S b/ports_smp/cortex_a78_smp/gnu/src/tx_thread_interrupt_control.S
index d4235180..21ec2dd1 100644
--- a/ports_smp/cortex_a78_smp/gnu/src/tx_thread_interrupt_control.S
+++ b/ports_smp/cortex_a78_smp/gnu/src/tx_thread_interrupt_control.S
@@ -19,7 +19,9 @@
/** */
/**************************************************************************/
/**************************************************************************/
-
+#ifdef TX_INCLUDE_USER_DEFINE_FILE
+#include "tx_user.h"
+#endif
.text
.align 3
@@ -28,7 +30,7 @@
/* FUNCTION RELEASE */
/* */
/* _tx_thread_interrupt_control ARMv8-A */
-/* 6.1.10 */
+/* 6.3.0 */
/* AUTHOR */
/* */
/* William E. Lamie, Microsoft Corporation */
diff --git a/ports_smp/cortex_a78_smp/gnu/src/tx_thread_interrupt_disable.S b/ports_smp/cortex_a78_smp/gnu/src/tx_thread_interrupt_disable.S
index 08f0e7e1..af2ef874 100644
--- a/ports_smp/cortex_a78_smp/gnu/src/tx_thread_interrupt_disable.S
+++ b/ports_smp/cortex_a78_smp/gnu/src/tx_thread_interrupt_disable.S
@@ -19,7 +19,9 @@
/** */
/**************************************************************************/
/**************************************************************************/
-
+#ifdef TX_INCLUDE_USER_DEFINE_FILE
+#include "tx_user.h"
+#endif
.text
.align 3
@@ -28,7 +30,7 @@
/* FUNCTION RELEASE */
/* */
/* _tx_thread_interrupt_disable ARMv8-A */
-/* 6.1.10 */
+/* 6.3.0 */
/* AUTHOR */
/* */
/* William E. Lamie, Microsoft Corporation */
diff --git a/ports_smp/cortex_a78_smp/gnu/src/tx_thread_interrupt_restore.S b/ports_smp/cortex_a78_smp/gnu/src/tx_thread_interrupt_restore.S
index d0191c32..3e0780d0 100644
--- a/ports_smp/cortex_a78_smp/gnu/src/tx_thread_interrupt_restore.S
+++ b/ports_smp/cortex_a78_smp/gnu/src/tx_thread_interrupt_restore.S
@@ -19,7 +19,9 @@
/** */
/**************************************************************************/
/**************************************************************************/
-
+#ifdef TX_INCLUDE_USER_DEFINE_FILE
+#include "tx_user.h"
+#endif
.text
.align 3
@@ -27,8 +29,8 @@
/* */
/* FUNCTION RELEASE */
/* */
-/* _tx_thread_interrupt_restore ARMv8-A-SMP */
-/* 6.1.10 */
+/* _tx_thread_interrupt_restore ARMv8-A */
+/* 6.3.0 */
/* AUTHOR */
/* */
/* William E. Lamie, Microsoft Corporation */
diff --git a/ports_smp/cortex_a78_smp/gnu/src/tx_thread_schedule.S b/ports_smp/cortex_a78_smp/gnu/src/tx_thread_schedule.S
index 782491cc..de6b70dd 100644
--- a/ports_smp/cortex_a78_smp/gnu/src/tx_thread_schedule.S
+++ b/ports_smp/cortex_a78_smp/gnu/src/tx_thread_schedule.S
@@ -19,7 +19,9 @@
/** */
/**************************************************************************/
/**************************************************************************/
-
+#ifdef TX_INCLUDE_USER_DEFINE_FILE
+#include "tx_user.h"
+#endif
.text
.align 3
@@ -28,7 +30,7 @@
/* FUNCTION RELEASE */
/* */
/* _tx_thread_schedule ARMv8-A-SMP */
-/* 6.1.10 */
+/* 6.3.0 */
/* AUTHOR */
/* */
/* William E. Lamie, Microsoft Corporation */
@@ -156,7 +158,7 @@ _tx_thread_ready_for_execution:
LDR x2, =_tx_thread_current_ptr // Pickup address of current thread
STR x0, [x2, x20, LSL #3] // Setup current thread pointer
-
+ DMB ISH
LDR x1, [x1, x20, LSL #3] // Reload the execute pointer
CMP w0, w1 // Did it change?
BEQ _execute_pointer_did_not_change // If not, skip handling
diff --git a/ports_smp/cortex_a78_smp/gnu/src/tx_thread_smp_core_get.S b/ports_smp/cortex_a78_smp/gnu/src/tx_thread_smp_core_get.S
index 4ffb8cc6..ea14c901 100644
--- a/ports_smp/cortex_a78_smp/gnu/src/tx_thread_smp_core_get.S
+++ b/ports_smp/cortex_a78_smp/gnu/src/tx_thread_smp_core_get.S
@@ -19,7 +19,9 @@
/** */
/**************************************************************************/
/**************************************************************************/
-
+#ifdef TX_INCLUDE_USER_DEFINE_FILE
+#include "tx_user.h"
+#endif
.text
.align 3
@@ -27,8 +29,8 @@
/* */
/* FUNCTION RELEASE */
/* */
-/* _tx_thread_smp_core_get Cortex-A35-SMP/AC6 */
-/* 6.1.10 */
+/* _tx_thread_smp_core_get ARMv8-A-SMP */
+/* 6.3.0 */
/* AUTHOR */
/* */
/* William E. Lamie, Microsoft Corporation */
diff --git a/ports_smp/cortex_a78_smp/gnu/src/tx_thread_smp_core_preempt.S b/ports_smp/cortex_a78_smp/gnu/src/tx_thread_smp_core_preempt.S
index 8dc6933c..1d28907f 100644
--- a/ports_smp/cortex_a78_smp/gnu/src/tx_thread_smp_core_preempt.S
+++ b/ports_smp/cortex_a78_smp/gnu/src/tx_thread_smp_core_preempt.S
@@ -19,6 +19,11 @@
/** */
/**************************************************************************/
/**************************************************************************/
+#ifdef TX_INCLUDE_USER_DEFINE_FILE
+#include "tx_user.h"
+#endif
+
+#define ICC_SGI1R_EL1 S3_0_C12_C11_5
.text
@@ -27,8 +32,8 @@
/* */
/* FUNCTION RELEASE */
/* */
-/* _tx_thread_smp_core_preempt Cortex-A35-SMP/AC6 */
-/* 6.1.10 */
+/* _tx_thread_smp_core_preempt ARMv8-A-SMP */
+/* 6.3.0 */
/* AUTHOR */
/* */
/* William E. Lamie, Microsoft Corporation */
diff --git a/ports_smp/cortex_a78_smp/gnu/src/tx_thread_smp_current_state_get.S b/ports_smp/cortex_a78_smp/gnu/src/tx_thread_smp_current_state_get.S
index edae94d5..707b41d2 100644
--- a/ports_smp/cortex_a78_smp/gnu/src/tx_thread_smp_current_state_get.S
+++ b/ports_smp/cortex_a78_smp/gnu/src/tx_thread_smp_current_state_get.S
@@ -19,7 +19,9 @@
/** */
/**************************************************************************/
/**************************************************************************/
-
+#ifdef TX_INCLUDE_USER_DEFINE_FILE
+#include "tx_user.h"
+#endif
.text
.align 3
@@ -27,8 +29,8 @@
/* */
/* FUNCTION RELEASE */
/* */
-/* _tx_thread_smp_current_state_get Cortex-A35-SMP/AC6 */
-/* 6.1.10 */
+/* _tx_thread_smp_current_state_get ARMv8-A-SMP */
+/* 6.3.0 */
/* AUTHOR */
/* */
/* William E. Lamie, Microsoft Corporation */
diff --git a/ports_smp/cortex_a78_smp/gnu/src/tx_thread_smp_current_thread_get.S b/ports_smp/cortex_a78_smp/gnu/src/tx_thread_smp_current_thread_get.S
index dd740e05..6c4bc9af 100644
--- a/ports_smp/cortex_a78_smp/gnu/src/tx_thread_smp_current_thread_get.S
+++ b/ports_smp/cortex_a78_smp/gnu/src/tx_thread_smp_current_thread_get.S
@@ -19,7 +19,9 @@
/** */
/**************************************************************************/
/**************************************************************************/
-
+#ifdef TX_INCLUDE_USER_DEFINE_FILE
+#include "tx_user.h"
+#endif
.text
.align 3
@@ -27,8 +29,8 @@
/* */
/* FUNCTION RELEASE */
/* */
-/* _tx_thread_smp_current_thread_get Cortex-A35-SMP/AC6 */
-/* 6.1.10 */
+/* _tx_thread_smp_current_thread_get ARMv8-A-SMP */
+/* 6.3.0 */
/* AUTHOR */
/* */
/* William E. Lamie, Microsoft Corporation */
diff --git a/ports_smp/cortex_a78_smp/gnu/src/tx_thread_smp_initialize_wait.S b/ports_smp/cortex_a78_smp/gnu/src/tx_thread_smp_initialize_wait.S
index 985136b5..defd791c 100644
--- a/ports_smp/cortex_a78_smp/gnu/src/tx_thread_smp_initialize_wait.S
+++ b/ports_smp/cortex_a78_smp/gnu/src/tx_thread_smp_initialize_wait.S
@@ -19,7 +19,9 @@
/** */
/**************************************************************************/
/**************************************************************************/
-
+#ifdef TX_INCLUDE_USER_DEFINE_FILE
+#include "tx_user.h"
+#endif
.text
.align 3
@@ -27,8 +29,8 @@
/* */
/* FUNCTION RELEASE */
/* */
-/* _tx_thread_smp_initialize_wait Cortex-A35-SMP/AC6 */
-/* 6.1.10 */
+/* _tx_thread_smp_initialize_wait ARMv8-A-SMP */
+/* 6.3.0 */
/* AUTHOR */
/* */
/* William E. Lamie, Microsoft Corporation */
diff --git a/ports_smp/cortex_a78_smp/gnu/src/tx_thread_smp_low_level_initialize.S b/ports_smp/cortex_a78_smp/gnu/src/tx_thread_smp_low_level_initialize.S
index 64b854d0..99b20d24 100644
--- a/ports_smp/cortex_a78_smp/gnu/src/tx_thread_smp_low_level_initialize.S
+++ b/ports_smp/cortex_a78_smp/gnu/src/tx_thread_smp_low_level_initialize.S
@@ -19,7 +19,9 @@
/** */
/**************************************************************************/
/**************************************************************************/
-
+#ifdef TX_INCLUDE_USER_DEFINE_FILE
+#include "tx_user.h"
+#endif
.text
.align 3
@@ -27,8 +29,8 @@
/* */
/* FUNCTION RELEASE */
/* */
-/* _tx_thread_smp_low_level_initialize Cortex-A35-SMP/AC6 */
-/* 6.1.10 */
+/* _tx_thread_smp_low_level_initialize ARMv8-A-SMP */
+/* 6.3.0 */
/* AUTHOR */
/* */
/* William E. Lamie, Microsoft Corporation */
diff --git a/ports_smp/cortex_a78_smp/gnu/src/tx_thread_smp_protect.S b/ports_smp/cortex_a78_smp/gnu/src/tx_thread_smp_protect.S
index 30a43701..1155a3fa 100644
--- a/ports_smp/cortex_a78_smp/gnu/src/tx_thread_smp_protect.S
+++ b/ports_smp/cortex_a78_smp/gnu/src/tx_thread_smp_protect.S
@@ -19,7 +19,9 @@
/** */
/**************************************************************************/
/**************************************************************************/
-
+#ifdef TX_INCLUDE_USER_DEFINE_FILE
+#include "tx_user.h"
+#endif
/* Include macros for modifying the wait list. */
#include "tx_thread_smp_protection_wait_list_macros.h"
@@ -31,8 +33,8 @@
/* */
/* FUNCTION RELEASE */
/* */
-/* _tx_thread_smp_protect Cortex-A35-SMP/AC6 */
-/* 6.1.10 */
+/* _tx_thread_smp_protect ARMv8-A-SMP */
+/* 6.3.0 */
/* AUTHOR */
/* */
/* William E. Lamie, Microsoft Corporation */
@@ -71,293 +73,49 @@ _tx_thread_smp_protect:
/* Pickup the CPU ID. */
- MRS x1, MPIDR_EL1 // Pickup the core ID
+ MRS x2, MPIDR_EL1 // Pickup the core ID
#ifdef TX_ARMV8_2
#if TX_THREAD_SMP_CLUSTERS > 1
- UBFX x7, x1, #16, #8 // Isolate cluster ID
+ UBFX x7, x2, #16, #8 // Isolate cluster ID
#endif
- UBFX x1, x1, #8, #8 // Isolate core ID
+ UBFX x2, x2, #8, #8 // Isolate core ID
#else
#if TX_THREAD_SMP_CLUSTERS > 1
- UBFX x7, x1, #8, #8 // Isolate cluster ID
+ UBFX x7, x2, #8, #8 // Isolate cluster ID
#endif
- UBFX x1, x1, #0, #8 // Isolate core ID
+ UBFX x2, x2, #0, #8 // Isolate core ID
#endif
#if TX_THREAD_SMP_CLUSTERS > 1
- ADDS x1, x1, x7, LSL #2 // Calculate CPU ID
+ ADDS x2, x2, x7, LSL #2 // Calculate CPU ID
#endif
- /* Do we already have protection? */
- // if (this_core == _tx_thread_smp_protection.tx_thread_smp_protect_core)
- // {
-
- LDR x2, =_tx_thread_smp_protection // Build address to protection structure
- LDR w3, [x2, #4] // Pickup the owning core
- CMP w1, w3 // Is it not this core?
- BNE _protection_not_owned // No, the protection is not already owned
-
- /* We already have protection. */
-
- /* Increment the protection count. */
- // _tx_thread_smp_protection.tx_thread_smp_protect_count++;
-
- LDR w3, [x2, #8] // Pickup ownership count
- ADD w3, w3, #1 // Increment ownership count
- STR w3, [x2, #8] // Store ownership count
- DMB ISH
-
- B _return
-
-_protection_not_owned:
-
- /* Is the lock available? */
- // if (_tx_thread_smp_protection.tx_thread_smp_protect_in_force == 0)
- // {
-
- LDAXR w3, [x2, #0] // Pickup the protection flag
- CMP w3, #0
- BNE _start_waiting // No, protection not available
-
- /* Is the list empty? */
- // if (_tx_thread_smp_protect_wait_list_head == _tx_thread_smp_protect_wait_list_tail)
- // {
-
- LDR x3, =_tx_thread_smp_protect_wait_list_head
- LDR w3, [x3]
- LDR x4, =_tx_thread_smp_protect_wait_list_tail
- LDR w4, [x4]
- CMP w3, w4
- BNE _list_not_empty
-
- /* Try to get the lock. */
- // if (write_exclusive(&_tx_thread_smp_protection.tx_thread_smp_protect_in_force, 1) == SUCCESS)
- // {
-
- MOV w3, #1 // Build lock value
- STXR w4, w3, [x2, #0] // Attempt to get the protection
- CMP w4, #0
- BNE _start_waiting // Did it fail?
-
- /* We got the lock! */
- // _tx_thread_smp_protect_lock_got();
-
- DMB ISH // Ensure write to protection finishes
- _tx_thread_smp_protect_lock_got // Call the lock got function
-
- B _return
-
-_list_not_empty:
-
- /* Are we at the front of the list? */
- // if (this_core == _tx_thread_smp_protect_wait_list[_tx_thread_smp_protect_wait_list_head])
- // {
-
- LDR x3, =_tx_thread_smp_protect_wait_list_head // Get the address of the head
- LDR w3, [x3] // Get the value of the head
- LDR x4, =_tx_thread_smp_protect_wait_list // Get the address of the list
- LDR w4, [x4, x3, LSL #2] // Get the value at the head index
-
- CMP w1, w4
- BNE _start_waiting
-
- /* Is the lock still available? */
- // if (_tx_thread_smp_protection.tx_thread_smp_protect_in_force == 0)
- // {
-
- LDAXR w3, [x2, #0] // Pickup the protection flag
- CMP w3, #0
- BNE _start_waiting // No, protection not available
-
- /* Get the lock. */
- // _tx_thread_smp_protection.tx_thread_smp_protect_in_force = 1;
-
- MOV w3, #1 // Build lock value
- STXR w4, w3, [x2, #0] // Attempt to get the protection
- CMP w4, #0
- BNE _start_waiting // Did it fail?
- DMB ISH //
-
- /* Got the lock. */
- // _tx_thread_smp_protect_lock_got();
-
- _tx_thread_smp_protect_lock_got
-
- /* Remove this core from the wait list. */
- // _tx_thread_smp_protect_remove_from_front_of_list();
-
- _tx_thread_smp_protect_remove_from_front_of_list
-
- B _return
-
-_start_waiting:
-
- /* For one reason or another, we didn't get the lock. */
-
- /* Increment wait count. */
- // _tx_thread_smp_protect_wait_counts[this_core]++;
-
- LDR x3, =_tx_thread_smp_protect_wait_counts // Load wait list counts
- LDR w4, [x3, x1, LSL #2] // Load waiting value for this core
- ADD w4, w4, #1 // Increment wait value
- STR w4, [x3, x1, LSL #2] // Store new wait value
-
- /* Have we not added ourselves to the list yet? */
- // if (_tx_thread_smp_protect_wait_counts[this_core] == 1)
- // {
-
- CMP w4, #1
- BNE _already_in_list0 // Is this core already waiting?
-
- /* Add ourselves to the list. */
- // _tx_thread_smp_protect_wait_list_add(this_core);
-
- _tx_thread_smp_protect_wait_list_add // Call macro to add ourselves to the list
-
- // }
-
-_already_in_list0:
-
- /* Restore interrupts. */
+ LDR x1, =_tx_thread_smp_protection // Build address to protection structure
+ LDR w3, [x1, #4] // Pickup the owning core
+ CMP w3, w2 // Is it this core?
+ BEQ _owned // Yes, the protection is already owned
+ LDAXR w4, [x1, #0] // Pickup the protection flag
+ CBZ w4, _get_protection // Yes, get the protection
MSR DAIF, x0 // Restore interrupts
ISB //
#ifdef TX_ENABLE_WFE
WFE // Go into standby
#endif
+ B _tx_thread_smp_protect // On waking, restart the protection attempt
- /* We do this until we have the lock. */
- // while (1)
- // {
-
-_try_to_get_lock:
-
- /* Disable interrupts so we don't get preempted. */
-
- MRS x0, DAIF // Pickup current interrupt posture
- MSR DAIFSet, 0x3 // Lockout interrupts
-
- /* Pickup the CPU ID. */
-
- MRS x1, MPIDR_EL1 // Pickup the core ID
-#ifdef TX_ARMV8_2
-#if TX_THREAD_SMP_CLUSTERS > 1
- UBFX x7, x1, #16, #8 // Isolate cluster ID
-#endif
- UBFX x1, x1, #8, #8 // Isolate core ID
-#else
-#if TX_THREAD_SMP_CLUSTERS > 1
- UBFX x7, x1, #8, #8 // Isolate cluster ID
-#endif
- UBFX x1, x1, #0, #8 // Isolate core ID
-#endif
-#if TX_THREAD_SMP_CLUSTERS > 1
- ADDS x1, x1, x7, LSL #2 // Calculate CPU ID
-#endif
-
- /* Do we already have protection? */
- // if (this_core == _tx_thread_smp_protection.tx_thread_smp_protect_core)
- // {
-
- LDR w3, [x2, #4] // Pickup the owning core
- CMP w3, w1 // Is it this core?
- BEQ _got_lock_after_waiting // Yes, the protection is already owned. This means
- // an ISR preempted us and got protection
-
- // }
-
- /* Are we at the front of the list? */
- // if (this_core == _tx_thread_smp_protect_wait_list[_tx_thread_smp_protect_wait_list_head])
- // {
-
- LDR x3, =_tx_thread_smp_protect_wait_list_head // Get the address of the head
- LDR w3, [x3] // Get the value of the head
- LDR x4, =_tx_thread_smp_protect_wait_list // Get the address of the list
- LDR w4, [x4, x3, LSL #2] // Get the value at the head index
-
- CMP w1, w4
- BNE _did_not_get_lock
-
- /* Is the lock still available? */
- // if (_tx_thread_smp_protection.tx_thread_smp_protect_in_force == 0)
- // {
-
- LDAXR w3, [x2, #0] // Pickup the protection flag
- CMP w3, #0
- BNE _did_not_get_lock // No, protection not available
-
- /* Get the lock. */
- // _tx_thread_smp_protection.tx_thread_smp_protect_in_force = 1;
-
- MOV w3, #1 // Build lock value
- STXR w4, w3, [x2, #0] // Attempt to get the protection
- CMP w4, #0
- BNE _did_not_get_lock // Did it fail?
- DMB ISH //
-
- /* Got the lock. */
- // _tx_thread_smp_protect_lock_got();
-
- _tx_thread_smp_protect_lock_got
-
- /* Remove this core from the wait list. */
- // _tx_thread_smp_protect_remove_from_front_of_list();
-
- _tx_thread_smp_protect_remove_from_front_of_list
-
- B _got_lock_after_waiting
-
-_did_not_get_lock:
-
- /* For one reason or another, we didn't get the lock. */
-
- /* Were we removed from the list? This can happen if we're a thread
- and we got preempted. */
- // if (_tx_thread_smp_protect_wait_counts[this_core] == 0)
- // {
-
- LDR x3, =_tx_thread_smp_protect_wait_counts // Load wait list counts
- LDR w4, [x3, x1, LSL #2] // Load waiting value for this core
- CMP w4, #0
- BNE _already_in_list1 // Is this core already in the list?
-
- /* Add ourselves to the list. */
- // _tx_thread_smp_protect_wait_list_add(this_core);
-
- _tx_thread_smp_protect_wait_list_add // Call macro to add ourselves to the list
-
- /* Our waiting count was also reset when we were preempted. Increment it again. */
- // _tx_thread_smp_protect_wait_counts[this_core]++;
-
- LDR x3, =_tx_thread_smp_protect_wait_counts // Load wait list counts
- LDR w4, [x3, x1, LSL #2] // Load waiting value for this core
- ADD w4, w4, #1 // Increment wait value
- STR w4, [x3, x1, LSL #2] // Store new wait value value
-
- // }
-
-_already_in_list1:
-
- /* Restore interrupts and try again. */
-
+_get_protection:
+ MOV x4, #1 // Build lock value
+ STXR w5, w4, [x1] // Attempt to get the protection
+ CBZ w5, _got_protection // Did it succeed? w5 = 0 means success!
MSR DAIF, x0 // Restore interrupts
- ISB //
-#ifdef TX_ENABLE_WFE
- WFE // Go into standby
-#endif
- B _try_to_get_lock // On waking, restart the protection attempt
-
-_got_lock_after_waiting:
-
- /* We're no longer waiting. */
- // _tx_thread_smp_protect_wait_counts[this_core]--;
-
- LDR x3, =_tx_thread_smp_protect_wait_counts // Load waiting list
- LDR w4, [x3, x1, LSL #2] // Load current wait value
- SUB w4, w4, #1 // Decrement wait value
- STR w4, [x3, x1, LSL #2] // Store new wait value value
-
- /* Restore registers and return. */
-
-_return:
+ B _tx_thread_smp_protect // Restart the protection attempt
+_got_protection:
+ DMB ISH //
+ STR w2, [x1, #4] // Save owning core
+_owned:
+ LDR w5, [x1, #8] // Pickup ownership count
+ ADD w5, w5, #1 // Increment ownership count
+ STR w5, [x1, #8] // Store ownership count
+ DMB ISH //
RET
diff --git a/ports_smp/cortex_a78_smp/gnu/src/tx_thread_smp_time_get.S b/ports_smp/cortex_a78_smp/gnu/src/tx_thread_smp_time_get.S
index f3045738..4bb9f1cb 100644
--- a/ports_smp/cortex_a78_smp/gnu/src/tx_thread_smp_time_get.S
+++ b/ports_smp/cortex_a78_smp/gnu/src/tx_thread_smp_time_get.S
@@ -9,6 +9,7 @@
* SPDX-License-Identifier: MIT
**************************************************************************/
+// Portions of this file were generated with AI assistance.
/**************************************************************************/
/**************************************************************************/
@@ -19,7 +20,9 @@
/** */
/**************************************************************************/
/**************************************************************************/
-
+#ifdef TX_INCLUDE_USER_DEFINE_FILE
+#include "tx_user.h"
+#endif
.text
.align 3
@@ -27,8 +30,8 @@
/* */
/* FUNCTION RELEASE */
/* */
-/* _tx_thread_smp_time_get Cortex-A35-SMP/AC6 */
-/* 6.1.10 */
+/* _tx_thread_smp_time_get ARMv8-A-SMP */
+/* 6.3.0 */
/* AUTHOR */
/* */
/* William E. Lamie, Microsoft Corporation */
@@ -58,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_smp/cortex_a78_smp/gnu/src/tx_thread_smp_unprotect.S b/ports_smp/cortex_a78_smp/gnu/src/tx_thread_smp_unprotect.S
index 49af176a..680e8bc8 100644
--- a/ports_smp/cortex_a78_smp/gnu/src/tx_thread_smp_unprotect.S
+++ b/ports_smp/cortex_a78_smp/gnu/src/tx_thread_smp_unprotect.S
@@ -19,7 +19,9 @@
/** */
/**************************************************************************/
/**************************************************************************/
-
+#ifdef TX_INCLUDE_USER_DEFINE_FILE
+#include "tx_user.h"
+#endif
.text
.align 3
@@ -27,8 +29,8 @@
/* */
/* FUNCTION RELEASE */
/* */
-/* _tx_thread_smp_unprotect Cortex-A35-SMP/AC6 */
-/* 6.1.10 */
+/* _tx_thread_smp_unprotect ARMv8-A-SMP */
+/* 6.3.0 */
/* AUTHOR */
/* */
/* William E. Lamie, Microsoft Corporation */
@@ -96,11 +98,6 @@ _tx_thread_smp_unprotect:
CMP w3, #0 // Is the preempt disable flag set?
BNE _still_protected // Yes, skip the protection release
- LDR x2,=_tx_thread_smp_protect_wait_counts // Build build address of wait counts
- LDR w3, [x2, x1, LSL #2] // Pickup wait list value
- CMP w3, #0 // Are any entities on this core waiting?
- BNE _still_protected // Yes, skip the protection release
-
LDR x2,=_tx_thread_smp_protection // Build address of protection structure
MOV w3, #0xFFFFFFFF // Build invalid value
STR w3, [x2, #4] // Mark the protected core as invalid
diff --git a/ports_smp/cortex_a78_smp/gnu/src/tx_thread_stack_build.S b/ports_smp/cortex_a78_smp/gnu/src/tx_thread_stack_build.S
index fa11a65c..581e259e 100644
--- a/ports_smp/cortex_a78_smp/gnu/src/tx_thread_stack_build.S
+++ b/ports_smp/cortex_a78_smp/gnu/src/tx_thread_stack_build.S
@@ -19,7 +19,9 @@
/** */
/**************************************************************************/
/**************************************************************************/
-
+#ifdef TX_INCLUDE_USER_DEFINE_FILE
+#include "tx_user.h"
+#endif
.text
.align 3
@@ -28,7 +30,7 @@
/* FUNCTION RELEASE */
/* */
/* _tx_thread_stack_build ARMv8-A-SMP */
-/* 6.1.10 */
+/* 6.3.0 */
/* AUTHOR */
/* */
/* William E. Lamie, Microsoft Corporation */
diff --git a/ports_smp/cortex_a78_smp/gnu/src/tx_thread_system_return.S b/ports_smp/cortex_a78_smp/gnu/src/tx_thread_system_return.S
index 4eebb9aa..23c75241 100644
--- a/ports_smp/cortex_a78_smp/gnu/src/tx_thread_system_return.S
+++ b/ports_smp/cortex_a78_smp/gnu/src/tx_thread_system_return.S
@@ -19,7 +19,9 @@
/** */
/**************************************************************************/
/**************************************************************************/
-
+#ifdef TX_INCLUDE_USER_DEFINE_FILE
+#include "tx_user.h"
+#endif
.text
.align 3
@@ -28,7 +30,7 @@
/* FUNCTION RELEASE */
/* */
/* _tx_thread_system_return ARMv8-A-SMP */
-/* 6.1.10 */
+/* 6.3.0 */
/* AUTHOR */
/* */
/* William E. Lamie, Microsoft Corporation */
@@ -159,6 +161,7 @@ __tx_thread_dont_save_ts:
/* Set ready bit in thread control block. */
+ DMB ISH // Ensure that accesses to shared resource have completed
MOV x3, #1 // Build ready value
STR w3, [x6, #260] // Make the thread ready
DMB ISH //
diff --git a/ports_smp/cortex_a78_smp/gnu/src/tx_timer_interrupt.S b/ports_smp/cortex_a78_smp/gnu/src/tx_timer_interrupt.S
index 6f90e5d1..5c6a6bc2 100644
--- a/ports_smp/cortex_a78_smp/gnu/src/tx_timer_interrupt.S
+++ b/ports_smp/cortex_a78_smp/gnu/src/tx_timer_interrupt.S
@@ -19,7 +19,9 @@
/** */
/**************************************************************************/
/**************************************************************************/
-
+#ifdef TX_INCLUDE_USER_DEFINE_FILE
+#include "tx_user.h"
+#endif
.text
.align 3
@@ -28,7 +30,7 @@
/* FUNCTION RELEASE */
/* */
/* _tx_timer_interrupt ARMv8-A-SMP */
-/* 6.1.10 */
+/* 6.3.0 */
/* AUTHOR */
/* */
/* William E. Lamie, Microsoft Corporation */
diff --git a/ports_smp/cortex_a7_smp/ac5/inc/tx_port.h b/ports_smp/cortex_a7_smp/ac5/inc/tx_port.h
index c5af63c8..80762931 100644
--- a/ports_smp/cortex_a7_smp/ac5/inc/tx_port.h
+++ b/ports_smp/cortex_a7_smp/ac5/inc/tx_port.h
@@ -388,7 +388,7 @@ void tx_thread_vfp_disable(void);
#ifdef TX_THREAD_INIT
CHAR _tx_version_id[] =
- "(c) 2024 Microsoft Corp. (c) 2026-present Eclipse ThreadX contributors. * ThreadX SMP/Cortex-A7/AC5 Version 6.5.1.202602a *";
+ "(c) 2024 Microsoft Corp. (c) 2026-present Eclipse ThreadX contributors. * ThreadX SMP/Cortex-A7/AC5 Version 6.5.2.202603 *";
#else
extern CHAR _tx_version_id[];
#endif
diff --git a/ports_smp/cortex_a7_smp/ac5/src/tx_thread_context_restore.s b/ports_smp/cortex_a7_smp/ac5/src/tx_thread_context_restore.s
index 78ddfee1..de76d8e6 100644
--- a/ports_smp/cortex_a7_smp/ac5/src/tx_thread_context_restore.s
+++ b/ports_smp/cortex_a7_smp/ac5/src/tx_thread_context_restore.s
@@ -1,5 +1,6 @@
;/***************************************************************************
; * Copyright (c) 2024 Microsoft Corporation
+; * 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
@@ -7,6 +8,7 @@
; *
; * SPDX-License-Identifier: MIT
; **************************************************************************/
+; Portions of this file were generated with AI assistance.
;
;
;/**************************************************************************/
@@ -29,8 +31,6 @@
;#include "tx_thread.h"
;#include "tx_timer.h"
;
-;/* Include macros for modifying the wait list. */
-#include "tx_thread_smp_protection_wait_list_macros.h"
IF :DEF:TX_ENABLE_FIQ_SUPPORT
DISABLE_INTS EQU 0xC0 ; Disable IRQ & FIQ interrupts
@@ -51,11 +51,6 @@ SVC_MODE EQU 0x93 ; SVC mode
IMPORT _tx_thread_preempt_disable
IMPORT _tx_timer_interrupt_active
IMPORT _tx_thread_smp_protection
- IMPORT _tx_thread_smp_protect_wait_counts
- IMPORT _tx_thread_smp_protect_wait_list
- IMPORT _tx_thread_smp_protect_wait_list_lock_protect_in_force
- IMPORT _tx_thread_smp_protect_wait_list_tail
- IMPORT _tx_thread_smp_protect_wait_list_size
IF :DEF:TX_ENABLE_EXECUTION_CHANGE_NOTIFY
IMPORT _tx_execution_isr_exit
ENDIF
@@ -195,76 +190,6 @@ __tx_thread_no_preempt_restore
; else
; {
__tx_thread_preempt_restore
-;
-; /* Was the thread being preempted waiting for the lock? */
-; if (_tx_thread_smp_protect_wait_counts[this_core] != 0)
-; {
-;
- LDR r1, =_tx_thread_smp_protect_wait_counts ; Load waiting count list
- LDR r2, [r1, r10, LSL #2] ; Load waiting value for this core
- CMP r2, #0
- BEQ _nobody_waiting_for_lock ; Is the core waiting for the lock?
-;
-; /* Do we not have the lock? This means the ISR never got the inter-core lock. */
-; if (_tx_thread_smp_protection.tx_thread_smp_protect_owned != this_core)
-; {
-;
- LDR r1, =_tx_thread_smp_protection ; Load address of protection structure
- LDR r2, [r1, #8] ; Pickup the owning core
- CMP r10, r2 ; Compare our core to the owning core
- BEQ _this_core_has_lock ; Do we have the lock?
-;
-; /* We don't have the lock. This core should be in the list. Remove it. */
-; _tx_thread_smp_protect_wait_list_remove(this_core);
-;
-macro_call0 _tx_thread_smp_protect_wait_list_remove ; Call macro to remove core from the list
- B _nobody_waiting_for_lock ; Leave
-;
-; }
-; else
-; {
-; /* We have the lock. This means the ISR got the inter-core lock, but
-; never released it because it saw that there was someone waiting.
-; Note this core is not in the list. */
-;
-_this_core_has_lock
-;
-; /* We're no longer waiting. Note that this should be zero since this happens during thread preemption. */
-; _tx_thread_smp_protect_wait_counts[core]--;
-;
- LDR r1, =_tx_thread_smp_protect_wait_counts ; Load waiting count list
- LDR r2, [r1, r10, LSL #2] ; Load waiting value for this core
- SUB r2, r2, #1 ; Decrement waiting value. Should be zero now
- STR r2, [r1, r10, LSL #2] ; Store new waiting value
-;
-; /* Now release the inter-core lock. */
-;
-; /* Set protected core as invalid. */
-; _tx_thread_smp_protection.tx_thread_smp_protect_core = 0xFFFFFFFF;
-;
- LDR r1, =_tx_thread_smp_protection ; Load address of protection structure
- MOV r2, #0xFFFFFFFF ; Build invalid value
- STR r2, [r1, #8] ; Mark the protected core as invalid
- DMB ; Ensure that accesses to shared resource have completed
-;
-; /* Release protection. */
-; _tx_thread_smp_protection.tx_thread_smp_protect_in_force = 0;
-;
- MOV r2, #0 ; Build release protection value
- STR r2, [r1, #0] ; Release the protection
- DSB ISH ; To ensure update of the protection occurs before other CPUs awake
-;
-; /* Wake up waiting processors. Note interrupts are already enabled. */
-;
- IF :DEF:TX_ENABLE_WFE
- SEV ; Send event to other CPUs
- ENDIF
-;
-; }
-; }
-;
-
-_nobody_waiting_for_lock
LDMIA sp!, {r3, r10, r12, lr} ; Recover temporarily saved registers
MOV r1, lr ; Save lr (point of interrupt)
diff --git a/ports_smp/cortex_a7_smp/ac5/src/tx_thread_context_save.s b/ports_smp/cortex_a7_smp/ac5/src/tx_thread_context_save.s
index acc2de11..289c0ea1 100644
--- a/ports_smp/cortex_a7_smp/ac5/src/tx_thread_context_save.s
+++ b/ports_smp/cortex_a7_smp/ac5/src/tx_thread_context_save.s
@@ -1,5 +1,6 @@
;/***************************************************************************
; * Copyright (c) 2024 Microsoft Corporation
+; * Copyright (c) 2026-present Eclipse ThreadX contributors
; *
; * This program and the accompanying materials are made available under the
; * terms of the MIT License which is available at
@@ -8,6 +9,7 @@
; * SPDX-License-Identifier: MIT
; **************************************************************************/
;
+; Portions of this file were generated with AI assistance.
;
;/**************************************************************************/
;/**************************************************************************/
@@ -145,11 +147,11 @@ __tx_thread_not_nested_save
BEQ __tx_thread_idle_system_save ; If so, interrupt occurred in
; scheduling loop - nothing needs saving!
;
-; /* Save the current stack pointer in the thread's control block. */
-; _tx_thread_current_ptr[core] -> tx_thread_stack_ptr = sp;
-;
-; /* Switch to the system stack. */
-; sp = _tx_thread_system_stack_ptr;
+; /* This routine runs in IRQ mode on this core's banked IRQ stack, which
+; serves as the system stack on this architecture, so there is no stack
+; switch to perform here. The thread's stack pointer is saved in its
+; control block by _tx_thread_context_restore, and only when the
+; interrupt results in preemption. */
;
MOV r10, #0 ; Clear stack limit
diff --git a/ports_smp/cortex_a7_smp/ac5/src/tx_thread_schedule.s b/ports_smp/cortex_a7_smp/ac5/src/tx_thread_schedule.s
index 1ced36e9..8ac992cd 100644
--- a/ports_smp/cortex_a7_smp/ac5/src/tx_thread_schedule.s
+++ b/ports_smp/cortex_a7_smp/ac5/src/tx_thread_schedule.s
@@ -1,5 +1,6 @@
;/***************************************************************************
; * Copyright (c) 2024 Microsoft Corporation
+; * 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
@@ -8,6 +9,8 @@
; * SPDX-License-Identifier: MIT
; **************************************************************************/
;
+; Portions of this file were generated with AI assistance.
+;
;
;/**************************************************************************/
;/**************************************************************************/
@@ -163,6 +166,7 @@ _tx_thread_ready_for_execution
LDR r2, =_tx_thread_current_ptr ; Pickup address of current thread
ADD r2, r2, r12 ; Build index into the current thread array
STR r0, [r2, #0] ; Setup current thread pointer
+ DMB ; Ensure the current thread pointer write completes
;
; /* In the time between reading the execute pointer and assigning
; it to the current pointer, the execute pointer was changed by
diff --git a/ports_smp/cortex_a7_smp/ac5/src/tx_thread_smp_protect.s b/ports_smp/cortex_a7_smp/ac5/src/tx_thread_smp_protect.s
index 5cc9f04e..48cce36f 100644
--- a/ports_smp/cortex_a7_smp/ac5/src/tx_thread_smp_protect.s
+++ b/ports_smp/cortex_a7_smp/ac5/src/tx_thread_smp_protect.s
@@ -1,5 +1,6 @@
;/***************************************************************************
; * Copyright (c) 2024 Microsoft Corporation
+; * 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
@@ -7,6 +8,7 @@
; *
; * SPDX-License-Identifier: MIT
; **************************************************************************/
+; Portions of this file were generated with AI assistance.
;
;
;/**************************************************************************/
@@ -29,17 +31,9 @@
;#include "tx_thread.h"
;#include "tx_timer.h" */
-;/* Include macros for modifying the wait list. */
-#include "tx_thread_smp_protection_wait_list_macros.h"
IMPORT _tx_thread_current_ptr
IMPORT _tx_thread_smp_protection
- IMPORT _tx_thread_smp_protect_wait_counts
- IMPORT _tx_thread_smp_protect_wait_list
- IMPORT _tx_thread_smp_protect_wait_list_lock_protect_in_force
- IMPORT _tx_thread_smp_protect_wait_list_head
- IMPORT _tx_thread_smp_protect_wait_list_tail
- IMPORT _tx_thread_smp_protect_wait_list_size
AREA ||.text||, CODE, READONLY
PRESERVE8
@@ -81,11 +75,9 @@ _tx_thread_smp_protect
;VOID _tx_thread_smp_protect(VOID)
;{
;
- PUSH {r4-r6} ; Save registers we'll be using
-;
; /* Disable interrupts so we don't get preempted. */
;
- MRS r0, CPSR ; Pickup current CPSR
+ MRS r3, CPSR ; Pickup current CPSR
IF :DEF:TX_ENABLE_FIQ_SUPPORT
CPSID if ; Disable IRQ and FIQ interrupts
@@ -93,266 +85,93 @@ _tx_thread_smp_protect
CPSID i ; Disable IRQ interrupts
ENDIF
;
+; /* Pickup the CPU ID. */
+;
+ MRC p15, 0, r2, c0, c0, 5 ; Read CPU ID register
+ AND r2, r2, #0x03 ; Mask off, leaving the CPU ID field
+;
; /* Do we already have protection? */
; if (this_core == _tx_thread_smp_protection.tx_thread_smp_protect_core)
; {
;
- MRC p15, 0, r1, c0, c0, 5 ; Read CPU ID register
- AND r1, r1, #0x03 ; Mask off, leaving the CPU ID field
- LDR r2, =_tx_thread_smp_protection ; Build address to protection structure
- LDR r3, [r2, #8] ; Pickup the owning core
- CMP r1, r3 ; Is it not this core?
- BNE _protection_not_owned ; No, the protection is not already owned
-;
-; /* We already have protection. */
-;
-; /* Increment the protection count. */
-; _tx_thread_smp_protection.tx_thread_smp_protect_count++;
+ LDR r0, =_tx_thread_smp_protection ; Build address to protection structure
+ LDR r1, [r0, #8] ; Pickup the owning core
+ CMP r1, r2 ; Is it this core?
+ BEQ _owned ; Yes, the protection is already owned
;
- LDR r3, [r2, #12] ; Pickup ownership count
- ADD r3, r3, #1 ; Increment ownership count
- STR r3, [r2, #12] ; Store ownership count
- DMB
-
- B _return
-
-_protection_not_owned
+; }
;
; /* Is the lock available? */
; if (_tx_thread_smp_protection.tx_thread_smp_protect_in_force == 0)
; {
;
- LDREX r3, [r2, #0] ; Pickup the protection flag
- CMP r3, #0
- BNE _start_waiting ; No, protection not available
-;
-; /* Is the list empty? */
-; if (_tx_thread_smp_protect_wait_list_head == _tx_thread_smp_protect_wait_list_tail)
-; {
-;
- LDR r3, =_tx_thread_smp_protect_wait_list_head
- LDR r3, [r3]
- LDR r4, =_tx_thread_smp_protect_wait_list_tail
- LDR r4, [r4]
- CMP r3, r4
- BNE _list_not_empty
-;
-; /* Try to get the lock. */
-; if (write_exclusive(&_tx_thread_smp_protection.tx_thread_smp_protect_in_force, 1) == SUCCESS)
-; {
-;
- MOV r3, #1 ; Build lock value
- STREX r4, r3, [r2, #0] ; Attempt to get the protection
- CMP r4, #0
- BNE _start_waiting ; Did it fail?
-;
-; /* We got the lock! */
-; _tx_thread_smp_protect_lock_got();
-;
- DMB ; Ensure write to protection finishes
-macro_call0 _tx_thread_smp_protect_lock_got ; Call the lock got function
-
- B _return
-
-_list_not_empty
-;
-; /* Are we at the front of the list? */
-; if (this_core == _tx_thread_smp_protect_wait_list[_tx_thread_smp_protect_wait_list_head])
-; {
-;
- LDR r3, =_tx_thread_smp_protect_wait_list_head ; Get the address of the head
- LDR r3, [r3] ; Get the value of the head
- LDR r4, =_tx_thread_smp_protect_wait_list ; Get the address of the list
- LDR r4, [r4, r3, LSL #2] ; Get the value at the head index
-
- CMP r1, r4
- BNE _start_waiting
-;
-; /* Is the lock still available? */
-; if (_tx_thread_smp_protection.tx_thread_smp_protect_in_force == 0)
-; {
-;
- LDR r3, [r2, #0] ; Pickup the protection flag
- CMP r3, #0
- BNE _start_waiting ; No, protection not available
-;
-; /* Get the lock. */
-; _tx_thread_smp_protection.tx_thread_smp_protect_in_force = 1;
-;
- MOV r3, #1 ; Build lock value
- STR r3, [r2, #0] ; Store lock value
- DMB ;
-;
-; /* Got the lock. */
-; _tx_thread_smp_protect_lock_got();
-;
-macro_call1 _tx_thread_smp_protect_lock_got
-;
-; /* Remove this core from the wait list. */
-; _tx_thread_smp_protect_remove_from_front_of_list();
-;
-macro_call2 _tx_thread_smp_protect_remove_from_front_of_list
-
- B _return
-
-_start_waiting
-;
-; /* For one reason or another, we didn't get the lock. */
-;
-; /* Increment wait count. */
-; _tx_thread_smp_protect_wait_counts[this_core]++;
-;
- LDR r3, =_tx_thread_smp_protect_wait_counts ; Load wait list counts
- LDR r4, [r3, r1, LSL #2] ; Load waiting value for this core
- ADD r4, r4, #1 ; Increment wait value
- STR r4, [r3, r1, LSL #2] ; Store new wait value
-;
-; /* Have we not added ourselves to the list yet? */
-; if (_tx_thread_smp_protect_wait_counts[this_core] == 1)
-; {
-;
- CMP r4, #1
- BNE _already_in_list0 ; Is this core already waiting?
-;
-; /* Add ourselves to the list. */
-; _tx_thread_smp_protect_wait_list_add(this_core);
-;
-macro_call3 _tx_thread_smp_protect_wait_list_add ; Call macro to add ourselves to the list
+ LDREX r1, [r0] ; Pickup the protection flag
+ CMP r1, #0 ; Is it available?
+ BEQ _get_protection ; Yes, attempt to get the protection
;
; }
;
-_already_in_list0
-;
-; /* Restore interrupts. */
+; /* The protection is held elsewhere. Restore interrupts so this core can be
+; preempted while it waits, then try the whole sequence again. */
;
- MSR CPSR_c, r0 ; Restore CPSR
+ MSR CPSR_c, r3 ; Restore CPSR
IF :DEF:TX_ENABLE_WFE
WFE ; Go into standby
ENDIF
-;
-; /* We do this until we have the lock. */
-; while (1)
-; {
-;
-_try_to_get_lock
-;
-; /* Disable interrupts so we don't get preempted. */
-;
- IF :DEF:TX_ENABLE_FIQ_SUPPORT
- CPSID if ; Disable IRQ and FIQ interrupts
- ELSE
- CPSID i ; Disable IRQ interrupts
- ENDIF
+ B _tx_thread_smp_protect ; On waking, restart the protection attempt
- MRC p15, 0, r1, c0, c0, 5 ; Read CPU ID register
- AND r1, r1, #0x03 ; Mask off, leaving the CPU ID field
+_get_protection
;
-; /* Do we already have protection? */
-; if (this_core == _tx_thread_smp_protection.tx_thread_smp_protect_core)
+; /* Try to get the lock. */
+; if (write_exclusive(&_tx_thread_smp_protection.tx_thread_smp_protect_in_force, 1) == SUCCESS)
; {
;
- LDR r3, [r2, #8] ; Pickup the owning core
- CMP r3, r1 ; Is it this core?
- BEQ _got_lock_after_waiting ; Yes, the protection is already owned. This means
- ; an ISR preempted us and got protection
+ MOV r1, #1 ; Build lock value
+ STREX r2, r1, [r0] ; Attempt to get the protection
+ CMP r2, #0 ; Check whether the store succeeded (0 = success)
+ BEQ _got_protection ; Yes, we have the protection
;
; }
;
-; /* Are we at the front of the list? */
-; if (this_core == _tx_thread_smp_protect_wait_list[_tx_thread_smp_protect_wait_list_head])
-; {
+; /* Another core beat us to it. Restore interrupts and try again. */
;
- LDR r3, =_tx_thread_smp_protect_wait_list_head ; Get the address of the head
- LDR r3, [r3] ; Get the value of the head
- LDR r4, =_tx_thread_smp_protect_wait_list ; Get the address of the list
- LDR r4, [r4, r3, LSL #2] ; Get the value at the head index
+ MSR CPSR_c, r3 ; Restore CPSR
+ B _tx_thread_smp_protect ; Try the whole process again
- CMP r1, r4
- BNE _did_not_get_lock
-;
-; /* Is the lock still available? */
-; if (_tx_thread_smp_protection.tx_thread_smp_protect_in_force == 0)
-; {
-;
- LDR r3, [r2, #0] ; Pickup the protection flag
- CMP r3, #0
- BNE _did_not_get_lock ; No, protection not available
-;
-; /* Get the lock. */
-; _tx_thread_smp_protection.tx_thread_smp_protect_in_force = 1;
-;
- MOV r3, #1 ; Build lock value
- STR r3, [r2, #0] ; Store lock value
- DMB ;
+_got_protection
;
-; /* Got the lock. */
-; _tx_thread_smp_protect_lock_got();
+; /* Got the lock. Record the owning core. */
+; _tx_thread_smp_protection.tx_thread_smp_protect_core = this_core;
;
-macro_call4 _tx_thread_smp_protect_lock_got
-;
-; /* Remove this core from the wait list. */
-; _tx_thread_smp_protect_remove_from_front_of_list();
-;
-macro_call5 _tx_thread_smp_protect_remove_from_front_of_list
-
- B _got_lock_after_waiting
+ DMB ; Ensure the protection write completes before it is used
+ MRC p15, 0, r2, c0, c0, 5 ; Read CPU ID register
+ AND r2, r2, #0x03 ; Mask off, leaving the CPU ID field
+ STR r2, [r0, #8] ; Save the owning core
-_did_not_get_lock
-;
-; /* For one reason or another, we didn't get the lock. */
-;
-; /* Were we removed from the list? This can happen if we're a thread
-; and we got preempted. */
-; if (_tx_thread_smp_protect_wait_counts[this_core] == 0)
-; {
-;
- LDR r3, =_tx_thread_smp_protect_wait_counts ; Load wait list counts
- LDR r4, [r3, r1, LSL #2] ; Load waiting value for this core
- CMP r4, #0
- BNE _already_in_list1 ; Is this core already in the list?
-;
-; /* Add ourselves to the list. */
-; _tx_thread_smp_protect_wait_list_add(this_core);
-;
-macro_call6 _tx_thread_smp_protect_wait_list_add ; Call macro to add ourselves to the list
-;
-; /* Our waiting count was also reset when we were preempted. Increment it again. */
-; _tx_thread_smp_protect_wait_counts[this_core]++;
-;
- LDR r3, =_tx_thread_smp_protect_wait_counts ; Load wait list counts
- LDR r4, [r3, r1, LSL #2] ; Load waiting value for this core
- ADD r4, r4, #1 ; Increment wait value
- STR r4, [r3, r1, LSL #2] ; Store new wait value value
-;
-; }
-;
-_already_in_list1
-;
-; /* Restore interrupts and try again. */
-;
- MSR CPSR_c, r0 ; Restore CPSR
- IF :DEF:TX_ENABLE_WFE
- WFE ; Go into standby
+ IF :DEF:TX_MPCORE_DEBUG_ENABLE
+ LSL r2, r2, #2 ; Build offset to array indexes
+ LDR r1, =_tx_thread_current_ptr ; Pickup start of the current thread array
+ ADD r1, r1, r2 ; Build index into the current thread array
+ LDR r2, [r1] ; Pickup current thread for this core
+ STR r2, [r0, #4] ; Save current thread pointer
+ STR LR, [r0, #16] ; Save caller's return address
+ STR r3, [r0, #20] ; Save CPSR
ENDIF
- B _try_to_get_lock ; On waking, restart the protection attempt
-_got_lock_after_waiting
+_owned
;
-; /* We're no longer waiting. */
-; _tx_thread_smp_protect_wait_counts[this_core]--;
+; /* Increment the protection count. */
+; _tx_thread_smp_protection.tx_thread_smp_protect_count++;
;
- LDR r3, =_tx_thread_smp_protect_wait_counts ; Load waiting list
- LDR r4, [r3, r1, LSL #2] ; Load current wait value
- SUB r4, r4, #1 ; Decrement wait value
- STR r4, [r3, r1, LSL #2] ; Store new wait value value
+ LDR r1, [r0, #12] ; Pickup ownership count
+ ADD r1, r1, #1 ; Increment ownership count
+ STR r1, [r0, #12] ; Store new ownership count
+ DMB ;
+ MOV r0, r3 ; Return the previous CPSR
;
-; /* Restore link register and return. */
+;}
;
-_return
-
- POP {r4-r6} ; Restore registers
-
IF {INTER} = {TRUE}
BX lr ; Return to caller
ELSE
@@ -360,4 +179,3 @@ _return
ENDIF
END
-
diff --git a/ports_smp/cortex_a7_smp/ac5/src/tx_thread_smp_protection_wait_list_macros.h b/ports_smp/cortex_a7_smp/ac5/src/tx_thread_smp_protection_wait_list_macros.h
deleted file mode 100644
index f7581458..00000000
--- a/ports_smp/cortex_a7_smp/ac5/src/tx_thread_smp_protection_wait_list_macros.h
+++ /dev/null
@@ -1,312 +0,0 @@
-;/***************************************************************************
-; * Copyright (c) 2024 Microsoft Corporation
-; *
-; * 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.
-; *
-; * SPDX-License-Identifier: MIT
-; **************************************************************************/
-;
-;
-;/**************************************************************************/
-;/**************************************************************************/
-;/** */
-;/** ThreadX Component */
-;/** */
-;/** Thread - Low Level SMP Support */
-;/** */
-;/**************************************************************************/
-;/**************************************************************************/
-
- MACRO
-$label _tx_thread_smp_protect_lock_got
-;
-; /* Set the currently owned core. */
-; _tx_thread_smp_protection.tx_thread_smp_protect_core = this_core;
-;
- STR r1, [r2, #8] ; Store this core
-;
-; /* Increment the protection count. */
-; _tx_thread_smp_protection.tx_thread_smp_protect_count++;
-;
- LDR r3, [r2, #12] ; Pickup ownership count
- ADD r3, r3, #1 ; Increment ownership count
- STR r3, [r2, #12] ; Store ownership count
- DMB
-
- IF :DEF:TX_MPCORE_DEBUG_ENABLE
- LSL r3, r1, #2 ; Build offset to array indexes
- LDR r4, =_tx_thread_current_ptr ; Pickup start of the current thread array
- ADD r4, r3, r4 ; Build index into the current thread array
- LDR r3, [r4] ; Pickup current thread for this core
- STR r3, [r2, #4] ; Save current thread pointer
- STR LR, [r2, #16] ; Save caller's return address
- STR r0, [r2, #20] ; Save CPSR
- ENDIF
-
- MEND
-
- MACRO
-$label _tx_thread_smp_protect_remove_from_front_of_list
-;
-; /* Remove ourselves from the list. */
-; _tx_thread_smp_protect_wait_list[_tx_thread_smp_protect_wait_list_head++] = 0xFFFFFFFF;
-;
- MOV r3, #0xFFFFFFFF ; Build the invalid core value
- LDR r4, =_tx_thread_smp_protect_wait_list_head ; Get the address of the head
- LDR r5, [r4] ; Get the value of the head
- LDR r6, =_tx_thread_smp_protect_wait_list ; Get the address of the list
- STR r3, [r6, r5, LSL #2] ; Store the invalid core value
- ADD r5, r5, #1 ; Increment the head
-;
-; /* Did we wrap? */
-; if (_tx_thread_smp_protect_wait_list_head == TX_THREAD_SMP_MAX_CORES + 1)
-; {
-;
- LDR r3, =_tx_thread_smp_protect_wait_list_size ; Load address of core list size
- LDR r3, [r3] ; Load the max cores value
- CMP r5, r3 ; Compare the head to it
- BNE $label._store_new_head ; Are we at the max?
-;
-; _tx_thread_smp_protect_wait_list_head = 0;
-;
- EOR r5, r5, r5 ; We're at the max. Set it to zero
-;
-; }
-;
-$label._store_new_head
-
- STR r5, [r4] ; Store the new head
-;
-; /* We have the lock! */
-; return;
-;
- MEND
-
-
- MACRO
-$label _tx_thread_smp_protect_wait_list_lock_get
-;VOID _tx_thread_smp_protect_wait_list_lock_get()
-;{
-; /* We do this until we have the lock. */
-; while (1)
-; {
-;
-$label._tx_thread_smp_protect_wait_list_lock_get__try_to_get_lock
-;
-; /* Is the list lock available? */
-; _tx_thread_smp_protect_wait_list_lock_protect_in_force = load_exclusive(&_tx_thread_smp_protect_wait_list_lock_protect_in_force);
-;
- LDR r1, =_tx_thread_smp_protect_wait_list_lock_protect_in_force
- LDREX r2, [r1] ; Pickup the protection flag
-;
-; if (protect_in_force == 0)
-; {
-;
- CMP r2, #0
- BNE $label._tx_thread_smp_protect_wait_list_lock_get__try_to_get_lock ; No, protection not available
-;
-; /* Try to get the list. */
-; int status = store_exclusive(&_tx_thread_smp_protect_wait_list_lock_protect_in_force, 1);
-;
- MOV r2, #1 ; Build lock value
- STREX r3, r2, [r1] ; Attempt to get the protection
-;
-; if (status == SUCCESS)
-;
- CMP r3, #0
- BNE $label._tx_thread_smp_protect_wait_list_lock_get__try_to_get_lock ; Did it fail? If so, try again.
-;
-; /* We have the lock! */
-; return;
-;
- MEND
-
-
- MACRO
-$label _tx_thread_smp_protect_wait_list_add
-;VOID _tx_thread_smp_protect_wait_list_add(UINT new_core)
-;{
-;
-; /* We're about to modify the list, so get the list lock. */
-; _tx_thread_smp_protect_wait_list_lock_get();
-;
- PUSH {r1-r2}
-
-$label _tx_thread_smp_protect_wait_list_lock_get
-
- POP {r1-r2}
-;
-; /* Add this core. */
-; _tx_thread_smp_protect_wait_list[_tx_thread_smp_protect_wait_list_tail++] = new_core;
-;
- LDR r3, =_tx_thread_smp_protect_wait_list_tail ; Get the address of the tail
- LDR r4, [r3] ; Get the value of tail
- LDR r5, =_tx_thread_smp_protect_wait_list ; Get the address of the list
- STR r1, [r5, r4, LSL #2] ; Store the new core value
- ADD r4, r4, #1 ; Increment the tail
-;
-; /* Did we wrap? */
-; if (_tx_thread_smp_protect_wait_list_tail == _tx_thread_smp_protect_wait_list_size)
-; {
-;
- LDR r5, =_tx_thread_smp_protect_wait_list_size ; Load max cores address
- LDR r5, [r5] ; Load max cores value
- CMP r4, r5 ; Compare max cores to tail
- BNE $label._tx_thread_smp_protect_wait_list_add__no_wrap ; Did we wrap?
-;
-; _tx_thread_smp_protect_wait_list_tail = 0;
-;
- MOV r4, #0
-;
-; }
-;
-$label._tx_thread_smp_protect_wait_list_add__no_wrap
-
- STR r4, [r3] ; Store the new tail value.
-;
-; /* Release the list lock. */
-; _tx_thread_smp_protect_wait_list_lock_protect_in_force = 0;
-;
- MOV r3, #0 ; Build lock value
- LDR r4, =_tx_thread_smp_protect_wait_list_lock_protect_in_force
- STR r3, [r4] ; Store the new value
-
- MEND
-
-
- MACRO
-$label _tx_thread_smp_protect_wait_list_remove
-;VOID _tx_thread_smp_protect_wait_list_remove(UINT core)
-;{
-;
-; /* Get the core index. */
-; UINT core_index;
-; for (core_index = 0;; core_index++)
-;
- EOR r1, r1, r1 ; Clear for 'core_index'
- LDR r2, =_tx_thread_smp_protect_wait_list ; Get the address of the list
-;
-; {
-;
-$label._tx_thread_smp_protect_wait_list_remove__check_cur_core
-;
-; /* Is this the core? */
-; if (_tx_thread_smp_protect_wait_list[core_index] == core)
-; {
-; break;
-;
- LDR r3, [r2, r1, LSL #2] ; Get the value at the current index
- CMP r3, r10 ; Did we find the core?
- BEQ $label._tx_thread_smp_protect_wait_list_remove__found_core
-;
-; }
-;
- ADD r1, r1, #1 ; Increment cur index
- B $label._tx_thread_smp_protect_wait_list_remove__check_cur_core ; Restart the loop
-;
-; }
-;
-$label._tx_thread_smp_protect_wait_list_remove__found_core
-;
-; /* We're about to modify the list. Get the lock. We need the lock because another
-; core could be simultaneously adding (a core is simultaneously trying to get
-; the inter-core lock) or removing (a core is simultaneously being preempted,
-; like what is currently happening). */
-; _tx_thread_smp_protect_wait_list_lock_get();
-;
- PUSH {r1}
-
-$label _tx_thread_smp_protect_wait_list_lock_get
-
- POP {r1}
-;
-; /* We remove by shifting. */
-; while (core_index != _tx_thread_smp_protect_wait_list_tail)
-; {
-;
-$label._tx_thread_smp_protect_wait_list_remove__compare_index_to_tail
-
- LDR r2, =_tx_thread_smp_protect_wait_list_tail ; Load tail address
- LDR r2, [r2] ; Load tail value
- CMP r1, r2 ; Compare cur index and tail
- BEQ $label._tx_thread_smp_protect_wait_list_remove__removed
-;
-; UINT next_index = core_index + 1;
-;
- MOV r2, r1 ; Move current index to next index register
- ADD r2, r2, #1 ; Add 1
-;
-; if (next_index == _tx_thread_smp_protect_wait_list_size)
-; {
-;
- LDR r3, =_tx_thread_smp_protect_wait_list_size
- LDR r3, [r3]
- CMP r2, r3
- BNE $label._tx_thread_smp_protect_wait_list_remove__next_index_no_wrap
-;
-; next_index = 0;
-;
- MOV r2, #0
-;
-; }
-;
-$label._tx_thread_smp_protect_wait_list_remove__next_index_no_wrap
-;
-; list_cores[core_index] = list_cores[next_index];
-;
- LDR r0, =_tx_thread_smp_protect_wait_list ; Get the address of the list
- LDR r3, [r0, r2, LSL #2] ; Get the value at the next index
- STR r3, [r0, r1, LSL #2] ; Store the value at the current index
-;
-; core_index = next_index;
-;
- MOV r1, r2
-
- B $label._tx_thread_smp_protect_wait_list_remove__compare_index_to_tail
-;
-; }
-;
-$label._tx_thread_smp_protect_wait_list_remove__removed
-;
-; /* Now update the tail. */
-; if (_tx_thread_smp_protect_wait_list_tail == 0)
-; {
-;
- LDR r0, =_tx_thread_smp_protect_wait_list_tail ; Load tail address
- LDR r1, [r0] ; Load tail value
- CMP r1, #0
- BNE $label._tx_thread_smp_protect_wait_list_remove__tail_not_zero
-;
-; _tx_thread_smp_protect_wait_list_tail = _tx_thread_smp_protect_wait_list_size;
-;
- LDR r2, =_tx_thread_smp_protect_wait_list_size
- LDR r1, [r2]
-;
-; }
-;
-$label._tx_thread_smp_protect_wait_list_remove__tail_not_zero
-;
-; _tx_thread_smp_protect_wait_list_tail--;
-;
- SUB r1, r1, #1
- STR r1, [r0] ; Store new tail value
-;
-; /* Release the list lock. */
-; _tx_thread_smp_protect_wait_list_lock_protect_in_force = 0;
-;
- MOV r0, #0 ; Build lock value
- LDR r1, =_tx_thread_smp_protect_wait_list_lock_protect_in_force ; Load lock address
- STR r0, [r1] ; Store the new value
-;
-; /* We're no longer waiting. Note that this should be zero since, again,
-; this function is only called when a thread preemption is occurring. */
-; _tx_thread_smp_protect_wait_counts[core]--;
-;
- LDR r1, =_tx_thread_smp_protect_wait_counts ; Load wait list counts
- LDR r2, [r1, r10, LSL #2] ; Load waiting value
- SUB r2, r2, #1 ; Subtract 1
- STR r2, [r1, r10, LSL #2] ; Store new waiting value
- MEND
-
diff --git a/ports_smp/cortex_a7_smp/ac5/src/tx_thread_smp_time_get.s b/ports_smp/cortex_a7_smp/ac5/src/tx_thread_smp_time_get.s
index 627d36f3..c63f6cc5 100644
--- a/ports_smp/cortex_a7_smp/ac5/src/tx_thread_smp_time_get.s
+++ b/ports_smp/cortex_a7_smp/ac5/src/tx_thread_smp_time_get.s
@@ -1,5 +1,6 @@
;/***************************************************************************
; * Copyright (c) 2024 Microsoft Corporation
+; * Copyright (c) 2026-present Eclipse ThreadX contributors
; *
; * This program and the accompanying materials are made available under the
; * terms of the MIT License which is available at
@@ -8,6 +9,7 @@
; * SPDX-License-Identifier: MIT
; **************************************************************************/
;
+; Portions of this file were generated with AI assistance.
;
;/**************************************************************************/
;/**************************************************************************/
@@ -68,8 +70,7 @@
EXPORT _tx_thread_smp_time_get
_tx_thread_smp_time_get
- MRC p15, 4, r0, c15, c0, 0 ; Read periph base address
- LDR r0, [r0, #0x604] ; Read count register
+ MRRC p15, 0, r0, r1, c14 ; Read generic timer physical count
IF {INTER} = {TRUE}
BX lr ; Return to caller
@@ -78,4 +79,3 @@ _tx_thread_smp_time_get
ENDIF
END
-
diff --git a/ports_smp/cortex_a7_smp/ac5/src/tx_thread_smp_unprotect.s b/ports_smp/cortex_a7_smp/ac5/src/tx_thread_smp_unprotect.s
index 260d13dc..f132cb40 100644
--- a/ports_smp/cortex_a7_smp/ac5/src/tx_thread_smp_unprotect.s
+++ b/ports_smp/cortex_a7_smp/ac5/src/tx_thread_smp_unprotect.s
@@ -1,5 +1,6 @@
;/***************************************************************************
; * Copyright (c) 2024 Microsoft Corporation
+; * 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
@@ -7,6 +8,7 @@
; *
; * SPDX-License-Identifier: MIT
; **************************************************************************/
+; Portions of this file were generated with AI assistance.
;
;
;/**************************************************************************/
@@ -33,7 +35,6 @@
IMPORT _tx_thread_current_ptr
IMPORT _tx_thread_smp_protection
IMPORT _tx_thread_preempt_disable
- IMPORT _tx_thread_smp_protect_wait_counts
AREA ||.text||, CODE, READONLY
PRESERVE8
@@ -103,10 +104,6 @@ _tx_thread_smp_unprotect
CMP r3, #0 ; Is the preempt disable flag set?
BNE _still_protected ; Yes, skip the protection release
- LDR r2,=_tx_thread_smp_protect_wait_counts ; Build build address of wait counts
- LDR r3, [r2, r1, LSL #2] ; Pickup wait list value
- CMP r3, #0 ; Are any entities on this core waiting?
- BNE _still_protected ; Yes, skip the protection release
LDR r2,=_tx_thread_smp_protection ; Build address of protection structure
MOV r3, #0xFFFFFFFF ; Build invalid value
diff --git a/ports_smp/cortex_a7_smp/ac5/src/tx_thread_system_return.s b/ports_smp/cortex_a7_smp/ac5/src/tx_thread_system_return.s
index ebd80ae2..84c8e036 100644
--- a/ports_smp/cortex_a7_smp/ac5/src/tx_thread_system_return.s
+++ b/ports_smp/cortex_a7_smp/ac5/src/tx_thread_system_return.s
@@ -1,5 +1,6 @@
;/***************************************************************************
; * Copyright (c) 2024 Microsoft Corporation
+; * Copyright (c) 2026-present Eclipse ThreadX contributors
; *
; * This program and the accompanying materials are made available under the
; * terms of the MIT License which is available at
@@ -8,6 +9,7 @@
; * SPDX-License-Identifier: MIT
; **************************************************************************/
;
+; Portions of this file were generated with AI assistance.
;
;/**************************************************************************/
;/**************************************************************************/
@@ -132,9 +134,10 @@ _tx_skip_solicited_vfp_save
ADD r2, r2, r12 ; Build index into time-slice array
LDR r1, [r2, #0] ; Pickup current time slice
;
-; /* Save current stack and switch to system stack. */
+; /* Save the current stack pointer in the thread's control block. The
+; scheduler runs on this core's banked SVC mode stack, which the startup
+; code set up, so there is no stack switch to perform. */
; _tx_thread_current_ptr[core] -> tx_thread_stack_ptr = sp;
-; sp = _tx_thread_system_stack_ptr[core];
;
STR sp, [r0, #8] ; Save thread stack pointer
;
diff --git a/ports_smp/cortex_a7_smp/ac5/src/tx_thread_vectored_context_save.s b/ports_smp/cortex_a7_smp/ac5/src/tx_thread_vectored_context_save.s
index 86145e1e..2d4b34a1 100644
--- a/ports_smp/cortex_a7_smp/ac5/src/tx_thread_vectored_context_save.s
+++ b/ports_smp/cortex_a7_smp/ac5/src/tx_thread_vectored_context_save.s
@@ -1,5 +1,6 @@
;/***************************************************************************
; * Copyright (c) 2024 Microsoft Corporation
+; * Copyright (c) 2026-present Eclipse ThreadX contributors
; *
; * This program and the accompanying materials are made available under the
; * terms of the MIT License which is available at
@@ -8,6 +9,7 @@
; * SPDX-License-Identifier: MIT
; **************************************************************************/
;
+; Portions of this file were generated with AI assistance.
;
;/**************************************************************************/
;/**************************************************************************/
@@ -143,11 +145,11 @@ __tx_thread_not_nested_save
;
; /* Note: Minimal context of interrupted thread is already saved. */
;
-; /* Save the current stack pointer in the thread's control block. */
-; _tx_thread_current_ptr[core] -> tx_thread_stack_ptr = sp;
-;
-; /* Switch to the system stack. */
-; sp = _tx_thread_system_stack_ptr[core];
+; /* This routine runs in IRQ mode on this core's banked IRQ stack, which
+; serves as the system stack on this architecture, so there is no stack
+; switch to perform here. The thread's stack pointer is saved in its
+; control block by _tx_thread_context_restore, and only when the
+; interrupt results in preemption. */
;
MOV r10, #0 ; Clear stack limit
diff --git a/ports_smp/cortex_a7_smp/gnu/CMakeLists.txt b/ports_smp/cortex_a7_smp/gnu/CMakeLists.txt
new file mode 100644
index 00000000..d4094f4d
--- /dev/null
+++ b/ports_smp/cortex_a7_smp/gnu/CMakeLists.txt
@@ -0,0 +1,37 @@
+# Copyright (c) 2026 Eclipse ThreadX contributors
+# SPDX-License-Identifier: MIT
+# Portions of this file were generated with AI assistance.
+#
+# ThreadX port sources for cortex_a7_smp, GNU tools.
+
+target_sources(${PROJECT_NAME}
+ PRIVATE
+ # {{BEGIN_TARGET_SOURCES}}
+ ${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_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_irq_nesting_end.S
+ ${CMAKE_CURRENT_LIST_DIR}/src/tx_thread_irq_nesting_start.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_stack_build.S
+ ${CMAKE_CURRENT_LIST_DIR}/src/tx_thread_system_return.S
+ ${CMAKE_CURRENT_LIST_DIR}/src/tx_thread_vectored_context_save.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_smp/cortex_a7_smp/gnu/example_build/build_threadx.sh b/ports_smp/cortex_a7_smp/gnu/example_build/build_threadx.sh
new file mode 100755
index 00000000..2f27e278
--- /dev/null
+++ b/ports_smp/cortex_a7_smp/gnu/example_build/build_threadx.sh
@@ -0,0 +1,295 @@
+#!/bin/sh
+##############################################################################
+# 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.
+#
+# SPDX-License-Identifier: MIT
+##############################################################################
+
+set -e
+cd "$(dirname "$0")"
+
+# this script builds the ThreadX library for the Cortex-A7 SMP port using
+# GNU toolchain or llvm/clang toolchain (defaults to GNU).
+: "${TOOLCHAIN:=gnu}"
+
+case "${TOOLCHAIN}" in
+ gnu)
+ CC="arm-none-eabi-gcc"
+ AR="arm-none-eabi-ar"
+ TARGET_FLAGS=""
+ ;;
+ atfe)
+ CC="${ATFE_CLANG:-clang}"
+ case "${CC}" in
+ */*) AR="$(dirname "${CC}")/llvm-ar" ;;
+ *) AR="llvm-ar" ;;
+ esac
+ TARGET_FLAGS="--target=arm-none-eabi"
+ ;;
+ *)
+ echo "Unknown TOOLCHAIN: ${TOOLCHAIN}" >&2
+ exit 1
+ ;;
+esac
+
+rm -f tx.a
+"${CC}" ${TARGET_FLAGS} -c -g -mcpu=cortex-a7 tx_initialize_low_level.S
+"${CC}" ${TARGET_FLAGS} -c -g -mcpu=cortex-a7 ../src/tx_thread_stack_build.S
+"${CC}" ${TARGET_FLAGS} -c -g -mcpu=cortex-a7 ../src/tx_thread_schedule.S
+"${CC}" ${TARGET_FLAGS} -c -g -mcpu=cortex-a7 ../src/tx_thread_system_return.S
+"${CC}" ${TARGET_FLAGS} -c -g -mcpu=cortex-a7 ../src/tx_thread_context_save.S
+"${CC}" ${TARGET_FLAGS} -c -g -mcpu=cortex-a7 ../src/tx_thread_context_restore.S
+"${CC}" ${TARGET_FLAGS} -c -g -mcpu=cortex-a7 ../src/tx_thread_interrupt_control.S
+"${CC}" ${TARGET_FLAGS} -c -g -mcpu=cortex-a7 ../src/tx_timer_interrupt.S
+"${CC}" ${TARGET_FLAGS} -c -g -mcpu=cortex-a7 ../src/tx_thread_interrupt_disable.S
+"${CC}" ${TARGET_FLAGS} -c -g -mcpu=cortex-a7 ../src/tx_thread_interrupt_restore.S
+"${CC}" ${TARGET_FLAGS} -c -g -mcpu=cortex-a7 ../src/tx_thread_irq_nesting_end.S
+"${CC}" ${TARGET_FLAGS} -c -g -mcpu=cortex-a7 ../src/tx_thread_irq_nesting_start.S
+"${CC}" ${TARGET_FLAGS} -c -g -mcpu=cortex-a7 ../src/tx_thread_vectored_context_save.S
+"${CC}" ${TARGET_FLAGS} -c -g -mcpu=cortex-a7 ../src/tx_thread_smp_core_get.S
+"${CC}" ${TARGET_FLAGS} -c -g -mcpu=cortex-a7 ../src/tx_thread_smp_core_preempt.S
+"${CC}" ${TARGET_FLAGS} -c -g -mcpu=cortex-a7 ../src/tx_thread_smp_current_state_get.S
+"${CC}" ${TARGET_FLAGS} -c -g -mcpu=cortex-a7 ../src/tx_thread_smp_current_thread_get.S
+"${CC}" ${TARGET_FLAGS} -c -g -mcpu=cortex-a7 ../src/tx_thread_smp_initialize_wait.S
+"${CC}" ${TARGET_FLAGS} -c -g -mcpu=cortex-a7 ../src/tx_thread_smp_low_level_initialize.S
+"${CC}" ${TARGET_FLAGS} -c -g -mcpu=cortex-a7 ../src/tx_thread_smp_protect.S
+"${CC}" ${TARGET_FLAGS} -c -g -mcpu=cortex-a7 ../src/tx_thread_smp_time_get.S
+"${CC}" ${TARGET_FLAGS} -c -g -mcpu=cortex-a7 ../src/tx_thread_smp_unprotect.S
+"${CC}" ${TARGET_FLAGS} -c -g -mcpu=cortex-a7 -I../../../../common_smp/inc -I../inc ../../../../common_smp/src/tx_block_allocate.c
+"${CC}" ${TARGET_FLAGS} -c -g -mcpu=cortex-a7 -I../../../../common_smp/inc -I../inc ../../../../common_smp/src/tx_block_pool_cleanup.c
+"${CC}" ${TARGET_FLAGS} -c -g -mcpu=cortex-a7 -I../../../../common_smp/inc -I../inc ../../../../common_smp/src/tx_block_pool_create.c
+"${CC}" ${TARGET_FLAGS} -c -g -mcpu=cortex-a7 -I../../../../common_smp/inc -I../inc ../../../../common_smp/src/tx_block_pool_delete.c
+"${CC}" ${TARGET_FLAGS} -c -g -mcpu=cortex-a7 -I../../../../common_smp/inc -I../inc ../../../../common_smp/src/tx_block_pool_info_get.c
+"${CC}" ${TARGET_FLAGS} -c -g -mcpu=cortex-a7 -I../../../../common_smp/inc -I../inc ../../../../common_smp/src/tx_block_pool_initialize.c
+"${CC}" ${TARGET_FLAGS} -c -g -mcpu=cortex-a7 -I../../../../common_smp/inc -I../inc ../../../../common_smp/src/tx_block_pool_performance_info_get.c
+"${CC}" ${TARGET_FLAGS} -c -g -mcpu=cortex-a7 -I../../../../common_smp/inc -I../inc ../../../../common_smp/src/tx_block_pool_performance_system_info_get.c
+"${CC}" ${TARGET_FLAGS} -c -g -mcpu=cortex-a7 -I../../../../common_smp/inc -I../inc ../../../../common_smp/src/tx_block_pool_prioritize.c
+"${CC}" ${TARGET_FLAGS} -c -g -mcpu=cortex-a7 -I../../../../common_smp/inc -I../inc ../../../../common_smp/src/tx_block_release.c
+"${CC}" ${TARGET_FLAGS} -c -g -mcpu=cortex-a7 -I../../../../common_smp/inc -I../inc ../../../../common_smp/src/tx_byte_allocate.c
+"${CC}" ${TARGET_FLAGS} -c -g -mcpu=cortex-a7 -I../../../../common_smp/inc -I../inc ../../../../common_smp/src/tx_byte_pool_cleanup.c
+"${CC}" ${TARGET_FLAGS} -c -g -mcpu=cortex-a7 -I../../../../common_smp/inc -I../inc ../../../../common_smp/src/tx_byte_pool_create.c
+"${CC}" ${TARGET_FLAGS} -c -g -mcpu=cortex-a7 -I../../../../common_smp/inc -I../inc ../../../../common_smp/src/tx_byte_pool_delete.c
+"${CC}" ${TARGET_FLAGS} -c -g -mcpu=cortex-a7 -I../../../../common_smp/inc -I../inc ../../../../common_smp/src/tx_byte_pool_info_get.c
+"${CC}" ${TARGET_FLAGS} -c -g -mcpu=cortex-a7 -I../../../../common_smp/inc -I../inc ../../../../common_smp/src/tx_byte_pool_initialize.c
+"${CC}" ${TARGET_FLAGS} -c -g -mcpu=cortex-a7 -I../../../../common_smp/inc -I../inc ../../../../common_smp/src/tx_byte_pool_performance_info_get.c
+"${CC}" ${TARGET_FLAGS} -c -g -mcpu=cortex-a7 -I../../../../common_smp/inc -I../inc ../../../../common_smp/src/tx_byte_pool_performance_system_info_get.c
+"${CC}" ${TARGET_FLAGS} -c -g -mcpu=cortex-a7 -I../../../../common_smp/inc -I../inc ../../../../common_smp/src/tx_byte_pool_prioritize.c
+"${CC}" ${TARGET_FLAGS} -c -g -mcpu=cortex-a7 -I../../../../common_smp/inc -I../inc ../../../../common_smp/src/tx_byte_pool_search.c
+"${CC}" ${TARGET_FLAGS} -c -g -mcpu=cortex-a7 -I../../../../common_smp/inc -I../inc ../../../../common_smp/src/tx_byte_release.c
+"${CC}" ${TARGET_FLAGS} -c -g -mcpu=cortex-a7 -I../../../../common_smp/inc -I../inc ../../../../common_smp/src/tx_event_flags_cleanup.c
+"${CC}" ${TARGET_FLAGS} -c -g -mcpu=cortex-a7 -I../../../../common_smp/inc -I../inc ../../../../common_smp/src/tx_event_flags_create.c
+"${CC}" ${TARGET_FLAGS} -c -g -mcpu=cortex-a7 -I../../../../common_smp/inc -I../inc ../../../../common_smp/src/tx_event_flags_delete.c
+"${CC}" ${TARGET_FLAGS} -c -g -mcpu=cortex-a7 -I../../../../common_smp/inc -I../inc ../../../../common_smp/src/tx_event_flags_get.c
+"${CC}" ${TARGET_FLAGS} -c -g -mcpu=cortex-a7 -I../../../../common_smp/inc -I../inc ../../../../common_smp/src/tx_event_flags_info_get.c
+"${CC}" ${TARGET_FLAGS} -c -g -mcpu=cortex-a7 -I../../../../common_smp/inc -I../inc ../../../../common_smp/src/tx_event_flags_initialize.c
+"${CC}" ${TARGET_FLAGS} -c -g -mcpu=cortex-a7 -I../../../../common_smp/inc -I../inc ../../../../common_smp/src/tx_event_flags_performance_info_get.c
+"${CC}" ${TARGET_FLAGS} -c -g -mcpu=cortex-a7 -I../../../../common_smp/inc -I../inc ../../../../common_smp/src/tx_event_flags_performance_system_info_get.c
+"${CC}" ${TARGET_FLAGS} -c -g -mcpu=cortex-a7 -I../../../../common_smp/inc -I../inc ../../../../common_smp/src/tx_event_flags_set.c
+"${CC}" ${TARGET_FLAGS} -c -g -mcpu=cortex-a7 -I../../../../common_smp/inc -I../inc ../../../../common_smp/src/tx_event_flags_set_notify.c
+"${CC}" ${TARGET_FLAGS} -c -g -mcpu=cortex-a7 -I../../../../common_smp/inc -I../inc ../../../../common_smp/src/tx_initialize_high_level.c
+"${CC}" ${TARGET_FLAGS} -c -g -mcpu=cortex-a7 -I../../../../common_smp/inc -I../inc ../../../../common_smp/src/tx_initialize_kernel_enter.c
+"${CC}" ${TARGET_FLAGS} -c -g -mcpu=cortex-a7 -I../../../../common_smp/inc -I../inc ../../../../common_smp/src/tx_initialize_kernel_setup.c
+"${CC}" ${TARGET_FLAGS} -c -g -mcpu=cortex-a7 -I../../../../common_smp/inc -I../inc ../../../../common_smp/src/tx_mutex_cleanup.c
+"${CC}" ${TARGET_FLAGS} -c -g -mcpu=cortex-a7 -I../../../../common_smp/inc -I../inc ../../../../common_smp/src/tx_mutex_create.c
+"${CC}" ${TARGET_FLAGS} -c -g -mcpu=cortex-a7 -I../../../../common_smp/inc -I../inc ../../../../common_smp/src/tx_mutex_delete.c
+"${CC}" ${TARGET_FLAGS} -c -g -mcpu=cortex-a7 -I../../../../common_smp/inc -I../inc ../../../../common_smp/src/tx_mutex_get.c
+"${CC}" ${TARGET_FLAGS} -c -g -mcpu=cortex-a7 -I../../../../common_smp/inc -I../inc ../../../../common_smp/src/tx_mutex_info_get.c
+"${CC}" ${TARGET_FLAGS} -c -g -mcpu=cortex-a7 -I../../../../common_smp/inc -I../inc ../../../../common_smp/src/tx_mutex_initialize.c
+"${CC}" ${TARGET_FLAGS} -c -g -mcpu=cortex-a7 -I../../../../common_smp/inc -I../inc ../../../../common_smp/src/tx_mutex_performance_info_get.c
+"${CC}" ${TARGET_FLAGS} -c -g -mcpu=cortex-a7 -I../../../../common_smp/inc -I../inc ../../../../common_smp/src/tx_mutex_performance_system_info_get.c
+"${CC}" ${TARGET_FLAGS} -c -g -mcpu=cortex-a7 -I../../../../common_smp/inc -I../inc ../../../../common_smp/src/tx_mutex_prioritize.c
+"${CC}" ${TARGET_FLAGS} -c -g -mcpu=cortex-a7 -I../../../../common_smp/inc -I../inc ../../../../common_smp/src/tx_mutex_priority_change.c
+"${CC}" ${TARGET_FLAGS} -c -g -mcpu=cortex-a7 -I../../../../common_smp/inc -I../inc ../../../../common_smp/src/tx_mutex_put.c
+"${CC}" ${TARGET_FLAGS} -c -g -mcpu=cortex-a7 -I../../../../common_smp/inc -I../inc ../../../../common_smp/src/tx_queue_cleanup.c
+"${CC}" ${TARGET_FLAGS} -c -g -mcpu=cortex-a7 -I../../../../common_smp/inc -I../inc ../../../../common_smp/src/tx_queue_create.c
+"${CC}" ${TARGET_FLAGS} -c -g -mcpu=cortex-a7 -I../../../../common_smp/inc -I../inc ../../../../common_smp/src/tx_queue_delete.c
+"${CC}" ${TARGET_FLAGS} -c -g -mcpu=cortex-a7 -I../../../../common_smp/inc -I../inc ../../../../common_smp/src/tx_queue_flush.c
+"${CC}" ${TARGET_FLAGS} -c -g -mcpu=cortex-a7 -I../../../../common_smp/inc -I../inc ../../../../common_smp/src/tx_queue_front_send.c
+"${CC}" ${TARGET_FLAGS} -c -g -mcpu=cortex-a7 -I../../../../common_smp/inc -I../inc ../../../../common_smp/src/tx_queue_info_get.c
+"${CC}" ${TARGET_FLAGS} -c -g -mcpu=cortex-a7 -I../../../../common_smp/inc -I../inc ../../../../common_smp/src/tx_queue_initialize.c
+"${CC}" ${TARGET_FLAGS} -c -g -mcpu=cortex-a7 -I../../../../common_smp/inc -I../inc ../../../../common_smp/src/tx_queue_performance_info_get.c
+"${CC}" ${TARGET_FLAGS} -c -g -mcpu=cortex-a7 -I../../../../common_smp/inc -I../inc ../../../../common_smp/src/tx_queue_performance_system_info_get.c
+"${CC}" ${TARGET_FLAGS} -c -g -mcpu=cortex-a7 -I../../../../common_smp/inc -I../inc ../../../../common_smp/src/tx_queue_prioritize.c
+"${CC}" ${TARGET_FLAGS} -c -g -mcpu=cortex-a7 -I../../../../common_smp/inc -I../inc ../../../../common_smp/src/tx_queue_receive.c
+"${CC}" ${TARGET_FLAGS} -c -g -mcpu=cortex-a7 -I../../../../common_smp/inc -I../inc ../../../../common_smp/src/tx_queue_send.c
+"${CC}" ${TARGET_FLAGS} -c -g -mcpu=cortex-a7 -I../../../../common_smp/inc -I../inc ../../../../common_smp/src/tx_queue_send_notify.c
+"${CC}" ${TARGET_FLAGS} -c -g -mcpu=cortex-a7 -I../../../../common_smp/inc -I../inc ../../../../common_smp/src/tx_semaphore_ceiling_put.c
+"${CC}" ${TARGET_FLAGS} -c -g -mcpu=cortex-a7 -I../../../../common_smp/inc -I../inc ../../../../common_smp/src/tx_semaphore_cleanup.c
+"${CC}" ${TARGET_FLAGS} -c -g -mcpu=cortex-a7 -I../../../../common_smp/inc -I../inc ../../../../common_smp/src/tx_semaphore_create.c
+"${CC}" ${TARGET_FLAGS} -c -g -mcpu=cortex-a7 -I../../../../common_smp/inc -I../inc ../../../../common_smp/src/tx_semaphore_delete.c
+"${CC}" ${TARGET_FLAGS} -c -g -mcpu=cortex-a7 -I../../../../common_smp/inc -I../inc ../../../../common_smp/src/tx_semaphore_get.c
+"${CC}" ${TARGET_FLAGS} -c -g -mcpu=cortex-a7 -I../../../../common_smp/inc -I../inc ../../../../common_smp/src/tx_semaphore_info_get.c
+"${CC}" ${TARGET_FLAGS} -c -g -mcpu=cortex-a7 -I../../../../common_smp/inc -I../inc ../../../../common_smp/src/tx_semaphore_initialize.c
+"${CC}" ${TARGET_FLAGS} -c -g -mcpu=cortex-a7 -I../../../../common_smp/inc -I../inc ../../../../common_smp/src/tx_semaphore_performance_info_get.c
+"${CC}" ${TARGET_FLAGS} -c -g -mcpu=cortex-a7 -I../../../../common_smp/inc -I../inc ../../../../common_smp/src/tx_semaphore_performance_system_info_get.c
+"${CC}" ${TARGET_FLAGS} -c -g -mcpu=cortex-a7 -I../../../../common_smp/inc -I../inc ../../../../common_smp/src/tx_semaphore_prioritize.c
+"${CC}" ${TARGET_FLAGS} -c -g -mcpu=cortex-a7 -I../../../../common_smp/inc -I../inc ../../../../common_smp/src/tx_semaphore_put.c
+"${CC}" ${TARGET_FLAGS} -c -g -mcpu=cortex-a7 -I../../../../common_smp/inc -I../inc ../../../../common_smp/src/tx_semaphore_put_notify.c
+"${CC}" ${TARGET_FLAGS} -c -g -mcpu=cortex-a7 -I../../../../common_smp/inc -I../inc ../../../../common_smp/src/tx_thread_create.c
+"${CC}" ${TARGET_FLAGS} -c -g -mcpu=cortex-a7 -I../../../../common_smp/inc -I../inc ../../../../common_smp/src/tx_thread_delete.c
+"${CC}" ${TARGET_FLAGS} -c -g -mcpu=cortex-a7 -I../../../../common_smp/inc -I../inc ../../../../common_smp/src/tx_thread_entry_exit_notify.c
+"${CC}" ${TARGET_FLAGS} -c -g -mcpu=cortex-a7 -I../../../../common_smp/inc -I../inc ../../../../common_smp/src/tx_thread_identify.c
+"${CC}" ${TARGET_FLAGS} -c -g -mcpu=cortex-a7 -I../../../../common_smp/inc -I../inc ../../../../common_smp/src/tx_thread_info_get.c
+"${CC}" ${TARGET_FLAGS} -c -g -mcpu=cortex-a7 -I../../../../common_smp/inc -I../inc ../../../../common_smp/src/tx_thread_initialize.c
+"${CC}" ${TARGET_FLAGS} -c -g -mcpu=cortex-a7 -I../../../../common_smp/inc -I../inc ../../../../common_smp/src/tx_thread_performance_info_get.c
+"${CC}" ${TARGET_FLAGS} -c -g -mcpu=cortex-a7 -I../../../../common_smp/inc -I../inc ../../../../common_smp/src/tx_thread_performance_system_info_get.c
+"${CC}" ${TARGET_FLAGS} -c -g -mcpu=cortex-a7 -I../../../../common_smp/inc -I../inc ../../../../common_smp/src/tx_thread_preemption_change.c
+"${CC}" ${TARGET_FLAGS} -c -g -mcpu=cortex-a7 -I../../../../common_smp/inc -I../inc ../../../../common_smp/src/tx_thread_priority_change.c
+"${CC}" ${TARGET_FLAGS} -c -g -mcpu=cortex-a7 -I../../../../common_smp/inc -I../inc ../../../../common_smp/src/tx_thread_relinquish.c
+"${CC}" ${TARGET_FLAGS} -c -g -mcpu=cortex-a7 -I../../../../common_smp/inc -I../inc ../../../../common_smp/src/tx_thread_reset.c
+"${CC}" ${TARGET_FLAGS} -c -g -mcpu=cortex-a7 -I../../../../common_smp/inc -I../inc ../../../../common_smp/src/tx_thread_resume.c
+"${CC}" ${TARGET_FLAGS} -c -g -mcpu=cortex-a7 -I../../../../common_smp/inc -I../inc ../../../../common_smp/src/tx_thread_shell_entry.c
+"${CC}" ${TARGET_FLAGS} -c -g -mcpu=cortex-a7 -I../../../../common_smp/inc -I../inc ../../../../common_smp/src/tx_thread_sleep.c
+"${CC}" ${TARGET_FLAGS} -c -g -mcpu=cortex-a7 -I../../../../common_smp/inc -I../inc ../../../../common_smp/src/tx_thread_stack_analyze.c
+"${CC}" ${TARGET_FLAGS} -c -g -mcpu=cortex-a7 -I../../../../common_smp/inc -I../inc ../../../../common_smp/src/tx_thread_stack_error_handler.c
+"${CC}" ${TARGET_FLAGS} -c -g -mcpu=cortex-a7 -I../../../../common_smp/inc -I../inc ../../../../common_smp/src/tx_thread_stack_error_notify.c
+"${CC}" ${TARGET_FLAGS} -c -g -mcpu=cortex-a7 -I../../../../common_smp/inc -I../inc ../../../../common_smp/src/tx_thread_suspend.c
+"${CC}" ${TARGET_FLAGS} -c -g -mcpu=cortex-a7 -I../../../../common_smp/inc -I../inc ../../../../common_smp/src/tx_thread_system_preempt_check.c
+"${CC}" ${TARGET_FLAGS} -c -g -mcpu=cortex-a7 -I../../../../common_smp/inc -I../inc ../../../../common_smp/src/tx_thread_system_resume.c
+"${CC}" ${TARGET_FLAGS} -c -g -mcpu=cortex-a7 -I../../../../common_smp/inc -I../inc ../../../../common_smp/src/tx_thread_system_suspend.c
+"${CC}" ${TARGET_FLAGS} -c -g -mcpu=cortex-a7 -I../../../../common_smp/inc -I../inc ../../../../common_smp/src/tx_thread_terminate.c
+"${CC}" ${TARGET_FLAGS} -c -g -mcpu=cortex-a7 -I../../../../common_smp/inc -I../inc ../../../../common_smp/src/tx_thread_time_slice.c
+"${CC}" ${TARGET_FLAGS} -c -g -mcpu=cortex-a7 -I../../../../common_smp/inc -I../inc ../../../../common_smp/src/tx_thread_time_slice_change.c
+"${CC}" ${TARGET_FLAGS} -c -g -mcpu=cortex-a7 -I../../../../common_smp/inc -I../inc ../../../../common_smp/src/tx_thread_timeout.c
+"${CC}" ${TARGET_FLAGS} -c -g -mcpu=cortex-a7 -I../../../../common_smp/inc -I../inc ../../../../common_smp/src/tx_thread_wait_abort.c
+"${CC}" ${TARGET_FLAGS} -c -g -mcpu=cortex-a7 -I../../../../common_smp/inc -I../inc ../../../../common_smp/src/tx_time_get.c
+"${CC}" ${TARGET_FLAGS} -c -g -mcpu=cortex-a7 -I../../../../common_smp/inc -I../inc ../../../../common_smp/src/tx_time_set.c
+"${CC}" ${TARGET_FLAGS} -c -g -mcpu=cortex-a7 -I../../../../common_smp/inc -I../inc ../../../../common_smp/src/tx_timer_activate.c
+"${CC}" ${TARGET_FLAGS} -c -g -mcpu=cortex-a7 -I../../../../common_smp/inc -I../inc ../../../../common_smp/src/tx_timer_change.c
+"${CC}" ${TARGET_FLAGS} -c -g -mcpu=cortex-a7 -I../../../../common_smp/inc -I../inc ../../../../common_smp/src/tx_timer_create.c
+"${CC}" ${TARGET_FLAGS} -c -g -mcpu=cortex-a7 -I../../../../common_smp/inc -I../inc ../../../../common_smp/src/tx_timer_deactivate.c
+"${CC}" ${TARGET_FLAGS} -c -g -mcpu=cortex-a7 -I../../../../common_smp/inc -I../inc ../../../../common_smp/src/tx_timer_delete.c
+"${CC}" ${TARGET_FLAGS} -c -g -mcpu=cortex-a7 -I../../../../common_smp/inc -I../inc ../../../../common_smp/src/tx_timer_expiration_process.c
+"${CC}" ${TARGET_FLAGS} -c -g -mcpu=cortex-a7 -I../../../../common_smp/inc -I../inc ../../../../common_smp/src/tx_timer_info_get.c
+"${CC}" ${TARGET_FLAGS} -c -g -mcpu=cortex-a7 -I../../../../common_smp/inc -I../inc ../../../../common_smp/src/tx_timer_initialize.c
+"${CC}" ${TARGET_FLAGS} -c -g -mcpu=cortex-a7 -I../../../../common_smp/inc -I../inc ../../../../common_smp/src/tx_timer_performance_info_get.c
+"${CC}" ${TARGET_FLAGS} -c -g -mcpu=cortex-a7 -I../../../../common_smp/inc -I../inc ../../../../common_smp/src/tx_timer_performance_system_info_get.c
+"${CC}" ${TARGET_FLAGS} -c -g -mcpu=cortex-a7 -I../../../../common_smp/inc -I../inc ../../../../common_smp/src/tx_timer_system_activate.c
+"${CC}" ${TARGET_FLAGS} -c -g -mcpu=cortex-a7 -I../../../../common_smp/inc -I../inc ../../../../common_smp/src/tx_timer_system_deactivate.c
+"${CC}" ${TARGET_FLAGS} -c -g -mcpu=cortex-a7 -I../../../../common_smp/inc -I../inc ../../../../common_smp/src/tx_timer_thread_entry.c
+"${CC}" ${TARGET_FLAGS} -c -g -mcpu=cortex-a7 -I../../../../common_smp/inc -I../inc ../../../../common_smp/src/tx_trace_enable.c
+"${CC}" ${TARGET_FLAGS} -c -g -mcpu=cortex-a7 -I../../../../common_smp/inc -I../inc ../../../../common_smp/src/tx_trace_disable.c
+"${CC}" ${TARGET_FLAGS} -c -g -mcpu=cortex-a7 -I../../../../common_smp/inc -I../inc ../../../../common_smp/src/tx_trace_initialize.c
+"${CC}" ${TARGET_FLAGS} -c -g -mcpu=cortex-a7 -I../../../../common_smp/inc -I../inc ../../../../common_smp/src/tx_trace_interrupt_control.c
+"${CC}" ${TARGET_FLAGS} -c -g -mcpu=cortex-a7 -I../../../../common_smp/inc -I../inc ../../../../common_smp/src/tx_trace_isr_enter_insert.c
+"${CC}" ${TARGET_FLAGS} -c -g -mcpu=cortex-a7 -I../../../../common_smp/inc -I../inc ../../../../common_smp/src/tx_trace_isr_exit_insert.c
+"${CC}" ${TARGET_FLAGS} -c -g -mcpu=cortex-a7 -I../../../../common_smp/inc -I../inc ../../../../common_smp/src/tx_trace_object_register.c
+"${CC}" ${TARGET_FLAGS} -c -g -mcpu=cortex-a7 -I../../../../common_smp/inc -I../inc ../../../../common_smp/src/tx_trace_object_unregister.c
+"${CC}" ${TARGET_FLAGS} -c -g -mcpu=cortex-a7 -I../../../../common_smp/inc -I../inc ../../../../common_smp/src/tx_trace_user_event_insert.c
+"${CC}" ${TARGET_FLAGS} -c -g -mcpu=cortex-a7 -I../../../../common_smp/inc -I../inc ../../../../common_smp/src/tx_trace_buffer_full_notify.c
+"${CC}" ${TARGET_FLAGS} -c -g -mcpu=cortex-a7 -I../../../../common_smp/inc -I../inc ../../../../common_smp/src/tx_trace_event_filter.c
+"${CC}" ${TARGET_FLAGS} -c -g -mcpu=cortex-a7 -I../../../../common_smp/inc -I../inc ../../../../common_smp/src/tx_trace_event_unfilter.c
+"${CC}" ${TARGET_FLAGS} -c -g -mcpu=cortex-a7 -I../../../../common_smp/inc -I../inc ../../../../common_smp/src/txe_block_allocate.c
+"${CC}" ${TARGET_FLAGS} -c -g -mcpu=cortex-a7 -I../../../../common_smp/inc -I../inc ../../../../common_smp/src/txe_block_pool_create.c
+"${CC}" ${TARGET_FLAGS} -c -g -mcpu=cortex-a7 -I../../../../common_smp/inc -I../inc ../../../../common_smp/src/txe_block_pool_delete.c
+"${CC}" ${TARGET_FLAGS} -c -g -mcpu=cortex-a7 -I../../../../common_smp/inc -I../inc ../../../../common_smp/src/txe_block_pool_info_get.c
+"${CC}" ${TARGET_FLAGS} -c -g -mcpu=cortex-a7 -I../../../../common_smp/inc -I../inc ../../../../common_smp/src/txe_block_pool_prioritize.c
+"${CC}" ${TARGET_FLAGS} -c -g -mcpu=cortex-a7 -I../../../../common_smp/inc -I../inc ../../../../common_smp/src/txe_block_release.c
+"${CC}" ${TARGET_FLAGS} -c -g -mcpu=cortex-a7 -I../../../../common_smp/inc -I../inc ../../../../common_smp/src/txe_byte_allocate.c
+"${CC}" ${TARGET_FLAGS} -c -g -mcpu=cortex-a7 -I../../../../common_smp/inc -I../inc ../../../../common_smp/src/txe_byte_pool_create.c
+"${CC}" ${TARGET_FLAGS} -c -g -mcpu=cortex-a7 -I../../../../common_smp/inc -I../inc ../../../../common_smp/src/txe_byte_pool_delete.c
+"${CC}" ${TARGET_FLAGS} -c -g -mcpu=cortex-a7 -I../../../../common_smp/inc -I../inc ../../../../common_smp/src/txe_byte_pool_info_get.c
+"${CC}" ${TARGET_FLAGS} -c -g -mcpu=cortex-a7 -I../../../../common_smp/inc -I../inc ../../../../common_smp/src/txe_byte_pool_prioritize.c
+"${CC}" ${TARGET_FLAGS} -c -g -mcpu=cortex-a7 -I../../../../common_smp/inc -I../inc ../../../../common_smp/src/txe_byte_release.c
+"${CC}" ${TARGET_FLAGS} -c -g -mcpu=cortex-a7 -I../../../../common_smp/inc -I../inc ../../../../common_smp/src/txe_event_flags_create.c
+"${CC}" ${TARGET_FLAGS} -c -g -mcpu=cortex-a7 -I../../../../common_smp/inc -I../inc ../../../../common_smp/src/txe_event_flags_delete.c
+"${CC}" ${TARGET_FLAGS} -c -g -mcpu=cortex-a7 -I../../../../common_smp/inc -I../inc ../../../../common_smp/src/txe_event_flags_get.c
+"${CC}" ${TARGET_FLAGS} -c -g -mcpu=cortex-a7 -I../../../../common_smp/inc -I../inc ../../../../common_smp/src/txe_event_flags_info_get.c
+"${CC}" ${TARGET_FLAGS} -c -g -mcpu=cortex-a7 -I../../../../common_smp/inc -I../inc ../../../../common_smp/src/txe_event_flags_set.c
+"${CC}" ${TARGET_FLAGS} -c -g -mcpu=cortex-a7 -I../../../../common_smp/inc -I../inc ../../../../common_smp/src/txe_event_flags_set_notify.c
+"${CC}" ${TARGET_FLAGS} -c -g -mcpu=cortex-a7 -I../../../../common_smp/inc -I../inc ../../../../common_smp/src/txe_mutex_create.c
+"${CC}" ${TARGET_FLAGS} -c -g -mcpu=cortex-a7 -I../../../../common_smp/inc -I../inc ../../../../common_smp/src/txe_mutex_delete.c
+"${CC}" ${TARGET_FLAGS} -c -g -mcpu=cortex-a7 -I../../../../common_smp/inc -I../inc ../../../../common_smp/src/txe_mutex_get.c
+"${CC}" ${TARGET_FLAGS} -c -g -mcpu=cortex-a7 -I../../../../common_smp/inc -I../inc ../../../../common_smp/src/txe_mutex_info_get.c
+"${CC}" ${TARGET_FLAGS} -c -g -mcpu=cortex-a7 -I../../../../common_smp/inc -I../inc ../../../../common_smp/src/txe_mutex_prioritize.c
+"${CC}" ${TARGET_FLAGS} -c -g -mcpu=cortex-a7 -I../../../../common_smp/inc -I../inc ../../../../common_smp/src/txe_mutex_put.c
+"${CC}" ${TARGET_FLAGS} -c -g -mcpu=cortex-a7 -I../../../../common_smp/inc -I../inc ../../../../common_smp/src/txe_queue_create.c
+"${CC}" ${TARGET_FLAGS} -c -g -mcpu=cortex-a7 -I../../../../common_smp/inc -I../inc ../../../../common_smp/src/txe_queue_delete.c
+"${CC}" ${TARGET_FLAGS} -c -g -mcpu=cortex-a7 -I../../../../common_smp/inc -I../inc ../../../../common_smp/src/txe_queue_flush.c
+"${CC}" ${TARGET_FLAGS} -c -g -mcpu=cortex-a7 -I../../../../common_smp/inc -I../inc ../../../../common_smp/src/txe_queue_front_send.c
+"${CC}" ${TARGET_FLAGS} -c -g -mcpu=cortex-a7 -I../../../../common_smp/inc -I../inc ../../../../common_smp/src/txe_queue_info_get.c
+"${CC}" ${TARGET_FLAGS} -c -g -mcpu=cortex-a7 -I../../../../common_smp/inc -I../inc ../../../../common_smp/src/txe_queue_prioritize.c
+"${CC}" ${TARGET_FLAGS} -c -g -mcpu=cortex-a7 -I../../../../common_smp/inc -I../inc ../../../../common_smp/src/txe_queue_receive.c
+"${CC}" ${TARGET_FLAGS} -c -g -mcpu=cortex-a7 -I../../../../common_smp/inc -I../inc ../../../../common_smp/src/txe_queue_send.c
+"${CC}" ${TARGET_FLAGS} -c -g -mcpu=cortex-a7 -I../../../../common_smp/inc -I../inc ../../../../common_smp/src/txe_queue_send_notify.c
+"${CC}" ${TARGET_FLAGS} -c -g -mcpu=cortex-a7 -I../../../../common_smp/inc -I../inc ../../../../common_smp/src/txe_semaphore_ceiling_put.c
+"${CC}" ${TARGET_FLAGS} -c -g -mcpu=cortex-a7 -I../../../../common_smp/inc -I../inc ../../../../common_smp/src/txe_semaphore_create.c
+"${CC}" ${TARGET_FLAGS} -c -g -mcpu=cortex-a7 -I../../../../common_smp/inc -I../inc ../../../../common_smp/src/txe_semaphore_delete.c
+"${CC}" ${TARGET_FLAGS} -c -g -mcpu=cortex-a7 -I../../../../common_smp/inc -I../inc ../../../../common_smp/src/txe_semaphore_get.c
+"${CC}" ${TARGET_FLAGS} -c -g -mcpu=cortex-a7 -I../../../../common_smp/inc -I../inc ../../../../common_smp/src/txe_semaphore_info_get.c
+"${CC}" ${TARGET_FLAGS} -c -g -mcpu=cortex-a7 -I../../../../common_smp/inc -I../inc ../../../../common_smp/src/txe_semaphore_prioritize.c
+"${CC}" ${TARGET_FLAGS} -c -g -mcpu=cortex-a7 -I../../../../common_smp/inc -I../inc ../../../../common_smp/src/txe_semaphore_put.c
+"${CC}" ${TARGET_FLAGS} -c -g -mcpu=cortex-a7 -I../../../../common_smp/inc -I../inc ../../../../common_smp/src/txe_semaphore_put_notify.c
+"${CC}" ${TARGET_FLAGS} -c -g -mcpu=cortex-a7 -I../../../../common_smp/inc -I../inc ../../../../common_smp/src/txe_thread_create.c
+"${CC}" ${TARGET_FLAGS} -c -g -mcpu=cortex-a7 -I../../../../common_smp/inc -I../inc ../../../../common_smp/src/txe_thread_delete.c
+"${CC}" ${TARGET_FLAGS} -c -g -mcpu=cortex-a7 -I../../../../common_smp/inc -I../inc ../../../../common_smp/src/txe_thread_entry_exit_notify.c
+"${CC}" ${TARGET_FLAGS} -c -g -mcpu=cortex-a7 -I../../../../common_smp/inc -I../inc ../../../../common_smp/src/txe_thread_info_get.c
+"${CC}" ${TARGET_FLAGS} -c -g -mcpu=cortex-a7 -I../../../../common_smp/inc -I../inc ../../../../common_smp/src/txe_thread_preemption_change.c
+"${CC}" ${TARGET_FLAGS} -c -g -mcpu=cortex-a7 -I../../../../common_smp/inc -I../inc ../../../../common_smp/src/txe_thread_priority_change.c
+"${CC}" ${TARGET_FLAGS} -c -g -mcpu=cortex-a7 -I../../../../common_smp/inc -I../inc ../../../../common_smp/src/txe_thread_relinquish.c
+"${CC}" ${TARGET_FLAGS} -c -g -mcpu=cortex-a7 -I../../../../common_smp/inc -I../inc ../../../../common_smp/src/txe_thread_reset.c
+"${CC}" ${TARGET_FLAGS} -c -g -mcpu=cortex-a7 -I../../../../common_smp/inc -I../inc ../../../../common_smp/src/txe_thread_resume.c
+"${CC}" ${TARGET_FLAGS} -c -g -mcpu=cortex-a7 -I../../../../common_smp/inc -I../inc ../../../../common_smp/src/txe_thread_suspend.c
+"${CC}" ${TARGET_FLAGS} -c -g -mcpu=cortex-a7 -I../../../../common_smp/inc -I../inc ../../../../common_smp/src/txe_thread_terminate.c
+"${CC}" ${TARGET_FLAGS} -c -g -mcpu=cortex-a7 -I../../../../common_smp/inc -I../inc ../../../../common_smp/src/txe_thread_time_slice_change.c
+"${CC}" ${TARGET_FLAGS} -c -g -mcpu=cortex-a7 -I../../../../common_smp/inc -I../inc ../../../../common_smp/src/txe_thread_wait_abort.c
+"${CC}" ${TARGET_FLAGS} -c -g -mcpu=cortex-a7 -I../../../../common_smp/inc -I../inc ../../../../common_smp/src/txe_timer_activate.c
+"${CC}" ${TARGET_FLAGS} -c -g -mcpu=cortex-a7 -I../../../../common_smp/inc -I../inc ../../../../common_smp/src/txe_timer_change.c
+"${CC}" ${TARGET_FLAGS} -c -g -mcpu=cortex-a7 -I../../../../common_smp/inc -I../inc ../../../../common_smp/src/txe_timer_create.c
+"${CC}" ${TARGET_FLAGS} -c -g -mcpu=cortex-a7 -I../../../../common_smp/inc -I../inc ../../../../common_smp/src/txe_timer_deactivate.c
+"${CC}" ${TARGET_FLAGS} -c -g -mcpu=cortex-a7 -I../../../../common_smp/inc -I../inc ../../../../common_smp/src/txe_timer_delete.c
+"${CC}" ${TARGET_FLAGS} -c -g -mcpu=cortex-a7 -I../../../../common_smp/inc -I../inc ../../../../common_smp/src/txe_timer_info_get.c
+"${CC}" ${TARGET_FLAGS} -c -g -mcpu=cortex-a7 -I../../../../common_smp/inc -I../inc ../../../../common_smp/src/tx_thread_smp_current_state_set.c
+"${CC}" ${TARGET_FLAGS} -c -g -mcpu=cortex-a7 -I../../../../common_smp/inc -I../inc ../../../../common_smp/src/tx_thread_smp_debug_entry_insert.c
+"${CC}" ${TARGET_FLAGS} -c -g -mcpu=cortex-a7 -I../../../../common_smp/inc -I../inc ../../../../common_smp/src/tx_thread_smp_high_level_initialize.c
+"${CC}" ${TARGET_FLAGS} -c -g -mcpu=cortex-a7 -I../../../../common_smp/inc -I../inc ../../../../common_smp/src/tx_thread_smp_rebalance_execute_list.c
+"${CC}" ${TARGET_FLAGS} -c -g -mcpu=cortex-a7 -I../../../../common_smp/inc -I../inc ../../../../common_smp/src/tx_thread_smp_core_exclude.c
+"${CC}" ${TARGET_FLAGS} -c -g -mcpu=cortex-a7 -I../../../../common_smp/inc -I../inc ../../../../common_smp/src/tx_thread_smp_core_exclude_get.c
+"${CC}" ${TARGET_FLAGS} -c -g -mcpu=cortex-a7 -I../../../../common_smp/inc -I../inc ../../../../common_smp/src/tx_timer_smp_core_exclude.c
+"${CC}" ${TARGET_FLAGS} -c -g -mcpu=cortex-a7 -I../../../../common_smp/inc -I../inc ../../../../common_smp/src/tx_timer_smp_core_exclude_get.c
+"${CC}" ${TARGET_FLAGS} -c -g -mcpu=cortex-a7 -I../../../../common_smp/inc -I../inc ../../../../common_smp/src/tx_thread_smp_utilities.c
+"${AR}" -r tx.a tx_thread_stack_build.o tx_thread_schedule.o tx_thread_system_return.o tx_thread_context_save.o tx_thread_context_restore.o tx_timer_interrupt.o tx_thread_interrupt_control.o
+"${AR}" -r tx.a tx_initialize_low_level.o tx_thread_interrupt_disable.o
+"${AR}" -r tx.a tx_thread_interrupt_restore.o tx_thread_irq_nesting_end.o tx_thread_irq_nesting_start.o
+"${AR}" -r tx.a tx_block_allocate.o tx_block_pool_cleanup.o tx_block_pool_create.o tx_block_pool_delete.o tx_block_pool_info_get.o
+"${AR}" -r tx.a tx_block_pool_initialize.o tx_block_pool_performance_info_get.o tx_block_pool_performance_system_info_get.o tx_block_pool_prioritize.o
+"${AR}" -r tx.a tx_block_release.o tx_byte_allocate.o tx_byte_pool_cleanup.o tx_byte_pool_create.o tx_byte_pool_delete.o tx_byte_pool_info_get.o
+"${AR}" -r tx.a tx_byte_pool_initialize.o tx_byte_pool_performance_info_get.o tx_byte_pool_performance_system_info_get.o tx_byte_pool_prioritize.o
+"${AR}" -r tx.a tx_byte_pool_search.o tx_byte_release.o tx_event_flags_cleanup.o tx_event_flags_create.o tx_event_flags_delete.o tx_event_flags_get.o
+"${AR}" -r tx.a tx_event_flags_info_get.o tx_event_flags_initialize.o tx_event_flags_performance_info_get.o tx_event_flags_performance_system_info_get.o
+"${AR}" -r tx.a tx_event_flags_set.o tx_event_flags_set_notify.o tx_initialize_high_level.o tx_initialize_kernel_enter.o tx_initialize_kernel_setup.o
+"${AR}" -r tx.a tx_mutex_cleanup.o tx_mutex_create.o tx_mutex_delete.o tx_mutex_get.o tx_mutex_info_get.o tx_mutex_initialize.o tx_mutex_performance_info_get.o
+"${AR}" -r tx.a tx_mutex_performance_system_info_get.o tx_mutex_prioritize.o tx_mutex_priority_change.o tx_mutex_put.o tx_queue_cleanup.o tx_queue_create.o
+"${AR}" -r tx.a tx_queue_delete.o tx_queue_flush.o tx_queue_front_send.o tx_queue_info_get.o tx_queue_initialize.o tx_queue_performance_info_get.o
+"${AR}" -r tx.a tx_queue_performance_system_info_get.o tx_queue_prioritize.o tx_queue_receive.o tx_queue_send.o tx_queue_send_notify.o tx_semaphore_ceiling_put.o
+"${AR}" -r tx.a tx_semaphore_cleanup.o tx_semaphore_create.o tx_semaphore_delete.o tx_semaphore_get.o tx_semaphore_info_get.o tx_semaphore_initialize.o
+"${AR}" -r tx.a tx_semaphore_performance_info_get.o tx_semaphore_performance_system_info_get.o tx_semaphore_prioritize.o tx_semaphore_put.o tx_semaphore_put_notify.o
+"${AR}" -r tx.a tx_thread_create.o tx_thread_delete.o tx_thread_entry_exit_notify.o tx_thread_identify.o tx_thread_info_get.o tx_thread_initialize.o
+"${AR}" -r tx.a tx_thread_performance_info_get.o tx_thread_performance_system_info_get.o tx_thread_preemption_change.o tx_thread_priority_change.o tx_thread_relinquish.o
+"${AR}" -r tx.a tx_thread_reset.o tx_thread_resume.o tx_thread_shell_entry.o tx_thread_sleep.o tx_thread_stack_analyze.o tx_thread_stack_error_handler.o
+"${AR}" -r tx.a tx_thread_stack_error_notify.o tx_thread_suspend.o tx_thread_system_preempt_check.o tx_thread_system_resume.o tx_thread_system_suspend.o
+"${AR}" -r tx.a tx_thread_terminate.o tx_thread_time_slice.o tx_thread_time_slice_change.o tx_thread_timeout.o tx_thread_wait_abort.o tx_time_get.o
+"${AR}" -r tx.a tx_time_set.o tx_timer_activate.o tx_timer_change.o tx_timer_create.o tx_timer_deactivate.o tx_timer_delete.o tx_timer_expiration_process.o
+"${AR}" -r tx.a tx_timer_info_get.o tx_timer_initialize.o tx_timer_performance_info_get.o tx_timer_performance_system_info_get.o tx_timer_system_activate.o
+"${AR}" -r tx.a tx_timer_system_deactivate.o tx_timer_thread_entry.o tx_trace_enable.o tx_trace_disable.o tx_trace_initialize.o tx_trace_interrupt_control.o
+"${AR}" -r tx.a tx_trace_isr_enter_insert.o tx_trace_isr_exit_insert.o tx_trace_object_register.o tx_trace_object_unregister.o tx_trace_user_event_insert.o
+"${AR}" -r tx.a tx_trace_buffer_full_notify.o tx_trace_event_filter.o tx_trace_event_unfilter.o
+"${AR}" -r tx.a txe_block_allocate.o txe_block_pool_create.o txe_block_pool_delete.o txe_block_pool_info_get.o txe_block_pool_prioritize.o txe_block_release.o
+"${AR}" -r tx.a txe_byte_allocate.o txe_byte_pool_create.o txe_byte_pool_delete.o txe_byte_pool_info_get.o txe_byte_pool_prioritize.o txe_byte_release.o
+"${AR}" -r tx.a txe_event_flags_create.o txe_event_flags_delete.o txe_event_flags_get.o txe_event_flags_info_get.o txe_event_flags_set.o
+"${AR}" -r tx.a txe_event_flags_set_notify.o txe_mutex_create.o txe_mutex_delete.o txe_mutex_get.o txe_mutex_info_get.o txe_mutex_prioritize.o
+"${AR}" -r tx.a txe_mutex_put.o txe_queue_create.o txe_queue_delete.o txe_queue_flush.o txe_queue_front_send.o txe_queue_info_get.o txe_queue_prioritize.o
+"${AR}" -r tx.a txe_queue_receive.o txe_queue_send.o txe_queue_send_notify.o txe_semaphore_ceiling_put.o txe_semaphore_create.o txe_semaphore_delete.o
+"${AR}" -r tx.a txe_semaphore_get.o txe_semaphore_info_get.o txe_semaphore_prioritize.o txe_semaphore_put.o txe_semaphore_put_notify.o txe_thread_create.o
+"${AR}" -r tx.a txe_thread_delete.o txe_thread_entry_exit_notify.o txe_thread_info_get.o txe_thread_preemption_change.o txe_thread_priority_change.o
+"${AR}" -r tx.a txe_thread_relinquish.o txe_thread_reset.o txe_thread_resume.o txe_thread_suspend.o txe_thread_terminate.o txe_thread_time_slice_change.o
+"${AR}" -r tx.a txe_thread_wait_abort.o txe_timer_activate.o txe_timer_change.o txe_timer_create.o txe_timer_deactivate.o txe_timer_delete.o txe_timer_info_get.o
+"${AR}" -r tx.a tx_thread_smp_current_state_set.o tx_thread_smp_debug_entry_insert.o tx_thread_smp_high_level_initialize.o
+"${AR}" -r tx.a tx_thread_smp_rebalance_execute_list.o tx_thread_smp_core_exclude.o tx_thread_smp_core_exclude_get.o
+"${AR}" -r tx.a tx_timer_smp_core_exclude.o tx_timer_smp_core_exclude_get.o tx_thread_smp_utilities.o
+"${AR}" -r tx.a tx_thread_smp_core_get.o tx_thread_smp_core_preempt.o tx_thread_smp_current_state_get.o tx_thread_smp_current_thread_get.o tx_thread_smp_initialize_wait.o
+"${AR}" -r tx.a tx_thread_smp_low_level_initialize.o tx_thread_smp_protect.o tx_thread_smp_time_get.o tx_thread_smp_unprotect.o
diff --git a/ports_smp/cortex_a7_smp/gnu/example_build/build_threadx_sample.sh b/ports_smp/cortex_a7_smp/gnu/example_build/build_threadx_sample.sh
new file mode 100755
index 00000000..c3475fab
--- /dev/null
+++ b/ports_smp/cortex_a7_smp/gnu/example_build/build_threadx_sample.sh
@@ -0,0 +1,54 @@
+#!/bin/sh
+##############################################################################
+# 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.
+#
+# SPDX-License-Identifier: MIT
+##############################################################################
+
+set -e
+cd "$(dirname "$0")"
+
+# this script builds the ThreadX sample image for the Cortex-A7 SMP port using
+# GNU toolchain or llvm/clang toolchain (defaults to GNU).
+: "${TOOLCHAIN:=gnu}"
+case "${TOOLCHAIN}" in
+ gnu)
+ CC="arm-none-eabi-gcc"
+ TARGET_FLAGS=""
+ # GNU and Clang use different driver syntax for selecting the program's
+ # entry-point symbol.
+ ENTRY_FLAG="-e Vectors"
+ # Bare-metal C libraries require syscall support. GNU uses newlib's nosys stubs
+ # while ATFE requires a semihost library.
+ SYSCALL_LIB="--specs=nosys.specs"
+ ;;
+ atfe)
+ CC="${ATFE_CLANG:-clang}"
+ TARGET_FLAGS="--target=arm-none-eabi"
+ ENTRY_FLAG="-Wl,--entry=Vectors"
+ SYSCALL_LIB="-lsemihost"
+ ;;
+ *)
+ echo "Unknown TOOLCHAIN: ${TOOLCHAIN}" >&2
+ exit 1
+ ;;
+esac
+
+"${CC}" ${TARGET_FLAGS} -c -g -I../../../../common_smp/inc -I../inc -mcpu=cortex-a7 sample_threadx.c
+"${CC}" ${TARGET_FLAGS} -c -g -mcpu=cortex-a7 startup.S
+"${CC}" ${TARGET_FLAGS} -c -g -mcpu=cortex-a7 crt0.S
+"${CC}" ${TARGET_FLAGS} -c -g -mcpu=cortex-a7 MP_GIC.S
+"${CC}" ${TARGET_FLAGS} -c -g -mcpu=cortex-a7 MP_Mutexes.S
+"${CC}" ${TARGET_FLAGS} -c -g -mcpu=cortex-a7 v7.S
+"${CC}" ${TARGET_FLAGS} -g -mcpu=cortex-a7 -nostartfiles \
+ -T sample_threadx.ld \
+ ${SYSCALL_LIB} \
+ ${ENTRY_FLAG} \
+ -o sample_threadx.out \
+ MP_GIC.o MP_Mutexes.o \
+ sample_threadx.o startup.o crt0.o v7.o tx.a \
+ -Wl,-M > sample_threadx.map
diff --git a/ports_smp/cortex_a7_smp/gnu/example_build/crt0.S b/ports_smp/cortex_a7_smp/gnu/example_build/crt0.S
new file mode 100644
index 00000000..abc817d5
--- /dev/null
+++ b/ports_smp/cortex_a7_smp/gnu/example_build/crt0.S
@@ -0,0 +1,101 @@
+
+ .syntax unified
+#if defined(THUMB_MODE)
+ .thumb
+#else
+ .arm
+#endif
+
+/* .text is used instead of .section .text so it works with arm-aout too. */
+ .text
+ .align 0
+
+#if defined(THUMB_MODE)
+ .thumb_func
+#endif
+ .global _mainCRTStartup
+_mainCRTStartup:
+#if defined(THUMB_MODE)
+ .thumb_func
+#endif
+ .global _start
+_start:
+#if defined(THUMB_MODE)
+ .thumb_func
+#endif
+ .global start
+start:
+
+/* Start by setting up a stack */
+ /* Set up the stack pointer to a fixed value */
+ ldr r3, .LC0
+ mov sp, r3
+ /* Setup a default stack-limit in case the code has been
+ compiled with "-mapcs-stack-check". Hard-wiring this value
+ is not ideal, since there is currently no support for
+ checking that the heap and stack have not collided, or that
+ this default 64k is enough for the program being executed.
+ However, it ensures that this simple crt0 world will not
+ immediately cause an overflow event: */
+ sub sl, sp, #64 << 10 /* Still assumes 256bytes below sl */
+ mov a2, #0 /* Second arg: fill value */
+ mov fp, a2 /* Null frame pointer */
+ mov r7, a2 /* Null frame pointer for Thumb */
+
+ ldr a1, .LC1 /* First arg: start of memory block */
+ ldr a3, .LC2
+ sub a3, a3, a1 /* Third arg: length of block */
+
+
+
+ bl memset
+ mov r0, #0 /* no arguments */
+ mov r1, #0 /* no argv either */
+#ifdef __USES_INITFINI__
+ /* Some arm/elf targets use the .init and .fini sections
+ to create constructors and destructors, and for these
+ targets we need to call the _init function and arrange
+ for _fini to be called at program exit. */
+ mov r4, r0
+ mov r5, r1
+/* ldr r0, .Lfini */
+ bl atexit
+/* bl init */
+ mov r0, r4
+ mov r1, r5
+#endif
+ bl main
+
+ bl exit /* Should not return. */
+
+
+ /* For Thumb, constants must be after the code since only
+ positive offsets are supported for PC relative addresses. */
+
+ .align 0
+.LC0:
+.LC1:
+ .word __bss_start__
+.LC2:
+ .word __bss_end__
+/*
+#ifdef __USES_INITFINI__
+.Lfini:
+ .word _fini
+#endif */
+ /* Return ... */
+ bx lr
+
+ .global _fini
+ .type _fini,function
+_fini:
+ BX lr // Return to caller
+
+/* Workspace for Angel calls. */
+ .data
+/* Data returned by monitor SWI. */
+.global __stack_base__
+HeapBase: .word 0
+HeapLimit: .word 0
+__stack_base__: .word 0
+StackLimit: .word 0
diff --git a/ports_smp/cortex_a7_smp/gnu/inc/tx_port.h b/ports_smp/cortex_a7_smp/gnu/inc/tx_port.h
index 93b89ff9..31725d3e 100644
--- a/ports_smp/cortex_a7_smp/gnu/inc/tx_port.h
+++ b/ports_smp/cortex_a7_smp/gnu/inc/tx_port.h
@@ -386,7 +386,7 @@ void tx_thread_vfp_disable(void);
#ifdef TX_THREAD_INIT
CHAR _tx_version_id[] =
- "(c) 2024 Microsoft Corp. (c) 2026-present Eclipse ThreadX contributors. * ThreadX SMP/Cortex-A7/GNU Version 6.5.1.202602a *";
+ "(c) 2024 Microsoft Corp. (c) 2026-present Eclipse ThreadX contributors. * ThreadX SMP/Cortex-A7/GNU Version 6.5.2.202603 *";
#else
extern CHAR _tx_version_id[];
#endif
diff --git a/ports_smp/cortex_a7_smp/gnu/src/tx_thread_context_restore.S b/ports_smp/cortex_a7_smp/gnu/src/tx_thread_context_restore.S
index 94e85ad3..b11e23ab 100644
--- a/ports_smp/cortex_a7_smp/gnu/src/tx_thread_context_restore.S
+++ b/ports_smp/cortex_a7_smp/gnu/src/tx_thread_context_restore.S
@@ -1,5 +1,6 @@
@/***************************************************************************
@ * Copyright (c) 2024 Microsoft Corporation
+@ * 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
@@ -7,6 +8,7 @@
@ *
@ * SPDX-License-Identifier: MIT
@ **************************************************************************/
+@ Portions of this file were generated with AI assistance.
@
@
@/**************************************************************************/
@@ -28,8 +30,6 @@
@#include "tx_api.h"
@#include "tx_thread.h"
@#include "tx_timer.h"
-@/* Include macros for modifying the wait list. */
-#include "tx_thread_smp_protection_wait_list_macros.h"
.arm
@@ -50,11 +50,6 @@ IRQ_MODE = 0x92 @ Disable IRQ, IRQ mode
.global _tx_thread_preempt_disable
.global _tx_timer_interrupt_active
.global _tx_thread_smp_protection
- .global _tx_thread_smp_protect_wait_counts
- .global _tx_thread_smp_protect_wait_list
- .global _tx_thread_smp_protect_wait_list_lock_protect_in_force
- .global _tx_thread_smp_protect_wait_list_tail
- .global _tx_thread_smp_protect_wait_list_size
#ifdef TX_ENABLE_EXECUTION_CHANGE_NOTIFY
.global _tx_execution_isr_exit
#endif
@@ -200,76 +195,6 @@ __tx_thread_no_preempt_restore:
@ else
@ {
__tx_thread_preempt_restore:
-@
-@ /* Was the thread being preempted waiting for the lock? */
-@ if (_tx_thread_smp_protect_wait_counts[this_core] != 0)
-@ {
-@
- LDR r1, =_tx_thread_smp_protect_wait_counts @ Load waiting count list
- LDR r2, [r1, r10, LSL #2] @ Load waiting value for this core
- CMP r2, #0
- BEQ _nobody_waiting_for_lock @ Is the core waiting for the lock?
-@
-@ /* Do we not have the lock? This means the ISR never got the inter-core lock. */
-@ if (_tx_thread_smp_protection.tx_thread_smp_protect_owned != this_core)
-@ {
-@
- LDR r1, =_tx_thread_smp_protection @ Load address of protection structure
- LDR r2, [r1, #8] @ Pickup the owning core
- CMP r10, r2 @ Compare our core to the owning core
- BEQ _this_core_has_lock @ Do we have the lock?
-@
-@ /* We don't have the lock. This core should be in the list. Remove it. */
-@ _tx_thread_smp_protect_wait_list_remove(this_core);
-@
- _tx_thread_smp_protect_wait_list_remove @ Call macro to remove core from the list
- B _nobody_waiting_for_lock @ Leave
-@
-@ }
-@ else
-@ {
-@ /* We have the lock. This means the ISR got the inter-core lock, but
-@ never released it because it saw that there was someone waiting.
-@ Note this core is not in the list. */
-@
-_this_core_has_lock:
-@
-@ /* We're no longer waiting. Note that this should be zero since this happens during thread preemption. */
-@ _tx_thread_smp_protect_wait_counts[core]--;
-@
- LDR r1, =_tx_thread_smp_protect_wait_counts @ Load waiting count list
- LDR r2, [r1, r10, LSL #2] @ Load waiting value for this core
- SUB r2, r2, #1 @ Decrement waiting value. Should be zero now
- STR r2, [r1, r10, LSL #2] @ Store new waiting value
-@
-@ /* Now release the inter-core lock. */
-@
-@ /* Set protected core as invalid. */
-@ _tx_thread_smp_protection.tx_thread_smp_protect_core = 0xFFFFFFFF;
-@
- LDR r1, =_tx_thread_smp_protection @ Load address of protection structure
- MOV r2, #0xFFFFFFFF @ Build invalid value
- STR r2, [r1, #8] @ Mark the protected core as invalid
- DMB @ Ensure that accesses to shared resource have completed
-@
-@ /* Release protection. */
-@ _tx_thread_smp_protection.tx_thread_smp_protect_in_force = 0;
-@
- MOV r2, #0 @ Build release protection value
- STR r2, [r1, #0] @ Release the protection
- DSB ISH @ To ensure update of the protection occurs before other CPUs awake
-@
-@ /* Wake up waiting processors. Note interrupts are already enabled. */
-@
-#ifdef TX_ENABLE_WFE
- SEV @ Send event to other CPUs
-#endif
-@
-@ }
-@ }
-@
-
-_nobody_waiting_for_lock:
LDMIA sp!, {r3, r10, r12, lr} @ Recover temporarily saved registers
MOV r1, lr @ Save lr (point of interrupt)
diff --git a/ports_smp/cortex_a7_smp/gnu/src/tx_thread_context_save.S b/ports_smp/cortex_a7_smp/gnu/src/tx_thread_context_save.S
index 448b3a5a..75a63ed4 100644
--- a/ports_smp/cortex_a7_smp/gnu/src/tx_thread_context_save.S
+++ b/ports_smp/cortex_a7_smp/gnu/src/tx_thread_context_save.S
@@ -1,5 +1,6 @@
@/***************************************************************************
@ * Copyright (c) 2024 Microsoft Corporation
+@ * Copyright (c) 2026-present Eclipse ThreadX contributors
@ *
@ * This program and the accompanying materials are made available under the
@ * terms of the MIT License which is available at
@@ -8,6 +9,7 @@
@ * SPDX-License-Identifier: MIT
@ **************************************************************************/
@
+@ Portions of this file were generated with AI assistance.
@
@/**************************************************************************/
@/**************************************************************************/
@@ -150,11 +152,11 @@ __tx_thread_not_nested_save:
BEQ __tx_thread_idle_system_save @ If so, interrupt occurred in
@ scheduling loop - nothing needs saving!
@
-@ /* Save the current stack pointer in the thread's control block. */
-@ _tx_thread_current_ptr[core] -> tx_thread_stack_ptr = sp;
-@
-@ /* Switch to the system stack. */
-@ sp = _tx_thread_system_stack_ptr;
+@ /* This routine runs in IRQ mode on this core's banked IRQ stack, which
+@ serves as the system stack on this architecture, so there is no stack
+@ switch to perform here. The thread's stack pointer is saved in its
+@ control block by _tx_thread_context_restore, and only when the
+@ interrupt results in preemption. */
@
MOV r10, #0 @ Clear stack limit
diff --git a/ports_smp/cortex_a7_smp/gnu/src/tx_thread_schedule.S b/ports_smp/cortex_a7_smp/gnu/src/tx_thread_schedule.S
index 88917752..a9e12749 100644
--- a/ports_smp/cortex_a7_smp/gnu/src/tx_thread_schedule.S
+++ b/ports_smp/cortex_a7_smp/gnu/src/tx_thread_schedule.S
@@ -1,5 +1,6 @@
@/***************************************************************************
@ * Copyright (c) 2024 Microsoft Corporation
+@ * 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
@@ -8,6 +9,8 @@
@ * SPDX-License-Identifier: MIT
@ **************************************************************************/
@
+@ Portions of this file were generated with AI assistance.
+@
@
@/**************************************************************************/
@/**************************************************************************/
@@ -180,6 +183,7 @@ _tx_thread_ready_for_execution:
LDR r2, =_tx_thread_current_ptr @ Pickup address of current thread
ADD r2, r2, r12 @ Build index into the current thread array
STR r0, [r2, #0] @ Setup current thread pointer
+ DMB @ Ensure the current thread pointer write completes
@
@ /* In the time between reading the execute pointer and assigning
@ it to the current pointer, the execute pointer was changed by
diff --git a/ports_smp/cortex_a7_smp/gnu/src/tx_thread_smp_protect.S b/ports_smp/cortex_a7_smp/gnu/src/tx_thread_smp_protect.S
index 4404585d..74dff802 100644
--- a/ports_smp/cortex_a7_smp/gnu/src/tx_thread_smp_protect.S
+++ b/ports_smp/cortex_a7_smp/gnu/src/tx_thread_smp_protect.S
@@ -1,5 +1,6 @@
@/***************************************************************************
@ * Copyright (c) 2024 Microsoft Corporation
+@ * 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
@@ -7,6 +8,7 @@
@ *
@ * SPDX-License-Identifier: MIT
@ **************************************************************************/
+@ Portions of this file were generated with AI assistance.
@
@
@/**************************************************************************/
@@ -29,17 +31,9 @@
@#include "tx_thread.h"
@#include "tx_timer.h" */
-@/* Include macros for modifying the wait list. */
-#include "tx_thread_smp_protection_wait_list_macros.h"
.global _tx_thread_current_ptr
.global _tx_thread_smp_protection
- .global _tx_thread_smp_protect_wait_counts
- .global _tx_thread_smp_protect_wait_list
- .global _tx_thread_smp_protect_wait_list_lock_protect_in_force
- .global _tx_thread_smp_protect_wait_list_head
- .global _tx_thread_smp_protect_wait_list_tail
- .global _tx_thread_smp_protect_wait_list_size
.arm
.text
@@ -83,11 +77,9 @@ _tx_thread_smp_protect:
@VOID _tx_thread_smp_protect(VOID)
@{
@
- PUSH {r4-r6} @ Save registers we'll be using
-@
@ /* Disable interrupts so we don't get preempted. */
@
- MRS r0, CPSR @ Pickup current CPSR
+ MRS r3, CPSR @ Pickup current CPSR
#ifdef TX_ENABLE_FIQ_SUPPORT
CPSID if @ Disable IRQ and FIQ interrupts
@@ -95,266 +87,93 @@ _tx_thread_smp_protect:
CPSID i @ Disable IRQ interrupts
#endif
@
+@ /* Pickup the CPU ID. */
+@
+ MRC p15, 0, r2, c0, c0, 5 @ Read CPU ID register
+ AND r2, r2, #0x03 @ Mask off, leaving the CPU ID field
+@
@ /* Do we already have protection? */
@ if (this_core == _tx_thread_smp_protection.tx_thread_smp_protect_core)
@ {
@
- MRC p15, 0, r1, c0, c0, 5 @ Read CPU ID register
- AND r1, r1, #0x03 @ Mask off, leaving the CPU ID field
- LDR r2, =_tx_thread_smp_protection @ Build address to protection structure
- LDR r3, [r2, #8] @ Pickup the owning core
- CMP r1, r3 @ Is it not this core?
- BNE _protection_not_owned @ No, the protection is not already owned
-@
-@ /* We already have protection. */
-@
-@ /* Increment the protection count. */
-@ _tx_thread_smp_protection.tx_thread_smp_protect_count++;
+ LDR r0, =_tx_thread_smp_protection @ Build address to protection structure
+ LDR r1, [r0, #8] @ Pickup the owning core
+ CMP r1, r2 @ Is it this core?
+ BEQ _owned @ Yes, the protection is already owned
@
- LDR r3, [r2, #12] @ Pickup ownership count
- ADD r3, r3, #1 @ Increment ownership count
- STR r3, [r2, #12] @ Store ownership count
- DMB
-
- B _return
-
-_protection_not_owned:
+@ }
@
@ /* Is the lock available? */
@ if (_tx_thread_smp_protection.tx_thread_smp_protect_in_force == 0)
@ {
@
- LDREX r3, [r2, #0] @ Pickup the protection flag
- CMP r3, #0
- BNE _start_waiting @ No, protection not available
-@
-@ /* Is the list empty? */
-@ if (_tx_thread_smp_protect_wait_list_head == _tx_thread_smp_protect_wait_list_tail)
-@ {
-@
- LDR r3, =_tx_thread_smp_protect_wait_list_head
- LDR r3, [r3]
- LDR r4, =_tx_thread_smp_protect_wait_list_tail
- LDR r4, [r4]
- CMP r3, r4
- BNE _list_not_empty
-@
-@ /* Try to get the lock. */
-@ if (write_exclusive(&_tx_thread_smp_protection.tx_thread_smp_protect_in_force, 1) == SUCCESS)
-@ {
-@
- MOV r3, #1 @ Build lock value
- STREX r4, r3, [r2, #0] @ Attempt to get the protection
- CMP r4, #0
- BNE _start_waiting @ Did it fail?
-@
-@ /* We got the lock! */
-@ _tx_thread_smp_protect_lock_got();
-@
- DMB @ Ensure write to protection finishes
- _tx_thread_smp_protect_lock_got @ Call the lock got function
-
- B _return
-
-_list_not_empty:
-@
-@ /* Are we at the front of the list? */
-@ if (this_core == _tx_thread_smp_protect_wait_list[_tx_thread_smp_protect_wait_list_head])
-@ {
-@
- LDR r3, =_tx_thread_smp_protect_wait_list_head @ Get the address of the head
- LDR r3, [r3] @ Get the value of the head
- LDR r4, =_tx_thread_smp_protect_wait_list @ Get the address of the list
- LDR r4, [r4, r3, LSL #2] @ Get the value at the head index
-
- CMP r1, r4
- BNE _start_waiting
-@
-@ /* Is the lock still available? */
-@ if (_tx_thread_smp_protection.tx_thread_smp_protect_in_force == 0)
-@ {
-@
- LDR r3, [r2, #0] @ Pickup the protection flag
- CMP r3, #0
- BNE _start_waiting @ No, protection not available
-@
-@ /* Get the lock. */
-@ _tx_thread_smp_protection.tx_thread_smp_protect_in_force = 1;
-@
- MOV r3, #1 @ Build lock value
- STR r3, [r2, #0] @ Store lock value
- DMB @
-@
-@ /* Got the lock. */
-@ _tx_thread_smp_protect_lock_got();
-@
- _tx_thread_smp_protect_lock_got
-@
-@ /* Remove this core from the wait list. */
-@ _tx_thread_smp_protect_remove_from_front_of_list();
-@
- _tx_thread_smp_protect_remove_from_front_of_list
-
- B _return
-
-_start_waiting:
-@
-@ /* For one reason or another, we didn't get the lock. */
-@
-@ /* Increment wait count. */
-@ _tx_thread_smp_protect_wait_counts[this_core]++;
-@
- LDR r3, =_tx_thread_smp_protect_wait_counts @ Load wait list counts
- LDR r4, [r3, r1, LSL #2] @ Load waiting value for this core
- ADD r4, r4, #1 @ Increment wait value
- STR r4, [r3, r1, LSL #2] @ Store new wait value
-@
-@ /* Have we not added ourselves to the list yet? */
-@ if (_tx_thread_smp_protect_wait_counts[this_core] == 1)
-@ {
-@
- CMP r4, #1
- BNE _already_in_list0 @ Is this core already waiting?
-@
-@ /* Add ourselves to the list. */
-@ _tx_thread_smp_protect_wait_list_add(this_core);
-@
- _tx_thread_smp_protect_wait_list_add @ Call macro to add ourselves to the list
+ LDREX r1, [r0] @ Pickup the protection flag
+ CMP r1, #0 @ Is it available?
+ BEQ _get_protection @ Yes, attempt to get the protection
@
@ }
@
-_already_in_list0:
+@ /* The protection is held elsewhere. Restore interrupts so this core can be
+@ preempted while it waits, then try the whole sequence again. */
@
-@ /* Restore interrupts. */
-@
- MSR CPSR_c, r0 @ Restore CPSR
+ MSR CPSR_c, r3 @ Restore CPSR
#ifdef TX_ENABLE_WFE
WFE @ Go into standby
#endif
-@
-@ /* We do this until we have the lock. */
-@ while (1)
-@ {
-@
-_try_to_get_lock:
-@
-@ /* Disable interrupts so we don't get preempted. */
-@
-#ifdef TX_ENABLE_FIQ_SUPPORT
- CPSID if @ Disable IRQ and FIQ interrupts
-#else
- CPSID i @ Disable IRQ interrupts
-#endif
+ B _tx_thread_smp_protect @ On waking, restart the protection attempt
- MRC p15, 0, r1, c0, c0, 5 @ Read CPU ID register
- AND r1, r1, #0x03 @ Mask off, leaving the CPU ID field
+_get_protection:
@
-@ /* Do we already have protection? */
-@ if (this_core == _tx_thread_smp_protection.tx_thread_smp_protect_core)
+@ /* Try to get the lock. */
+@ if (write_exclusive(&_tx_thread_smp_protection.tx_thread_smp_protect_in_force, 1) == SUCCESS)
@ {
@
- LDR r3, [r2, #8] @ Pickup the owning core
- CMP r3, r1 @ Is it this core?
- BEQ _got_lock_after_waiting @ Yes, the protection is already owned. This means
- @ an ISR preempted us and got protection
+ MOV r1, #1 @ Build lock value
+ STREX r2, r1, [r0] @ Attempt to get the protection
+ CMP r2, #0 @ Check whether the store succeeded (0 = success)
+ BEQ _got_protection @ Yes, we have the protection
@
@ }
@
-@ /* Are we at the front of the list? */
-@ if (this_core == _tx_thread_smp_protect_wait_list[_tx_thread_smp_protect_wait_list_head])
-@ {
+@ /* Another core beat us to it. Restore interrupts and try again. */
@
- LDR r3, =_tx_thread_smp_protect_wait_list_head @ Get the address of the head
- LDR r3, [r3] @ Get the value of the head
- LDR r4, =_tx_thread_smp_protect_wait_list @ Get the address of the list
- LDR r4, [r4, r3, LSL #2] @ Get the value at the head index
+ MSR CPSR_c, r3 @ Restore CPSR
+ B _tx_thread_smp_protect @ Try the whole process again
- CMP r1, r4
- BNE _did_not_get_lock
-@
-@ /* Is the lock still available? */
-@ if (_tx_thread_smp_protection.tx_thread_smp_protect_in_force == 0)
-@ {
-@
- LDR r3, [r2, #0] @ Pickup the protection flag
- CMP r3, #0
- BNE _did_not_get_lock @ No, protection not available
-@
-@ /* Get the lock. */
-@ _tx_thread_smp_protection.tx_thread_smp_protect_in_force = 1;
-@
- MOV r3, #1 @ Build lock value
- STR r3, [r2, #0] @ Store lock value
- DMB @
-@
-@ /* Got the lock. */
-@ _tx_thread_smp_protect_lock_got();
-@
- _tx_thread_smp_protect_lock_got
+_got_protection:
@
-@ /* Remove this core from the wait list. */
-@ _tx_thread_smp_protect_remove_from_front_of_list();
+@ /* Got the lock. Record the owning core. */
+@ _tx_thread_smp_protection.tx_thread_smp_protect_core = this_core;
@
- _tx_thread_smp_protect_remove_from_front_of_list
+ DMB @ Ensure the protection write completes before it is used
+ MRC p15, 0, r2, c0, c0, 5 @ Read CPU ID register
+ AND r2, r2, #0x03 @ Mask off, leaving the CPU ID field
+ STR r2, [r0, #8] @ Save the owning core
- B _got_lock_after_waiting
-
-_did_not_get_lock:
-@
-@ /* For one reason or another, we didn't get the lock. */
-@
-@ /* Were we removed from the list? This can happen if we're a thread
-@ and we got preempted. */
-@ if (_tx_thread_smp_protect_wait_counts[this_core] == 0)
-@ {
-@
- LDR r3, =_tx_thread_smp_protect_wait_counts @ Load wait list counts
- LDR r4, [r3, r1, LSL #2] @ Load waiting value for this core
- CMP r4, #0
- BNE _already_in_list1 @ Is this core already in the list?
-@
-@ /* Add ourselves to the list. */
-@ _tx_thread_smp_protect_wait_list_add(this_core);
-@
- _tx_thread_smp_protect_wait_list_add @ Call macro to add ourselves to the list
-@
-@ /* Our waiting count was also reset when we were preempted. Increment it again. */
-@ _tx_thread_smp_protect_wait_counts[this_core]++;
-@
- LDR r3, =_tx_thread_smp_protect_wait_counts @ Load wait list counts
- LDR r4, [r3, r1, LSL #2] @ Load waiting value for this core
- ADD r4, r4, #1 @ Increment wait value
- STR r4, [r3, r1, LSL #2] @ Store new wait value value
-@
-@ }
-@
-_already_in_list1:
-@
-@ /* Restore interrupts and try again. */
-@
- MSR CPSR_c, r0 @ Restore CPSR
-#ifdef TX_ENABLE_WFE
- WFE @ Go into standby
+#ifdef TX_MPCORE_DEBUG_ENABLE
+ LSL r2, r2, #2 @ Build offset to array indexes
+ LDR r1, =_tx_thread_current_ptr @ Pickup start of the current thread array
+ ADD r1, r1, r2 @ Build index into the current thread array
+ LDR r2, [r1] @ Pickup current thread for this core
+ STR r2, [r0, #4] @ Save current thread pointer
+ STR LR, [r0, #16] @ Save caller's return address
+ STR r3, [r0, #20] @ Save CPSR
#endif
- B _try_to_get_lock @ On waking, restart the protection attempt
-_got_lock_after_waiting:
+_owned:
@
-@ /* We're no longer waiting. */
-@ _tx_thread_smp_protect_wait_counts[this_core]--;
+@ /* Increment the protection count. */
+@ _tx_thread_smp_protection.tx_thread_smp_protect_count++;
@
- LDR r3, =_tx_thread_smp_protect_wait_counts @ Load waiting list
- LDR r4, [r3, r1, LSL #2] @ Load current wait value
- SUB r4, r4, #1 @ Decrement wait value
- STR r4, [r3, r1, LSL #2] @ Store new wait value value
+ LDR r1, [r0, #12] @ Pickup ownership count
+ ADD r1, r1, #1 @ Increment ownership count
+ STR r1, [r0, #12] @ Store new ownership count
+ DMB @
+ MOV r0, r3 @ Return the previous CPSR
@
-@ /* Restore link register and return. */
+@}
@
-_return:
-
- POP {r4-r6} @ Restore registers
-
#ifdef __THUMB_INTERWORK
BX lr @ Return to caller
#else
diff --git a/ports_smp/cortex_a7_smp/gnu/src/tx_thread_smp_protection_wait_list_macros.h b/ports_smp/cortex_a7_smp/gnu/src/tx_thread_smp_protection_wait_list_macros.h
deleted file mode 100644
index dff747d1..00000000
--- a/ports_smp/cortex_a7_smp/gnu/src/tx_thread_smp_protection_wait_list_macros.h
+++ /dev/null
@@ -1,308 +0,0 @@
-@/***************************************************************************
-@ * Copyright (c) 2024 Microsoft Corporation
-@ *
-@ * 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.
-@ *
-@ * SPDX-License-Identifier: MIT
-@ **************************************************************************/
-@
-@
-@/**************************************************************************/
-@/**************************************************************************/
-@/** */
-@/** ThreadX Component */
-@/** */
-@/** Thread - Low Level SMP Support */
-@/** */
-@/**************************************************************************/
-@/**************************************************************************/
-
- .macro _tx_thread_smp_protect_lock_got
-@
-@ /* Set the currently owned core. */
-@ _tx_thread_smp_protection.tx_thread_smp_protect_core = this_core;
-@
- STR r1, [r2, #8] @ Store this core
-@
-@ /* Increment the protection count. */
-@ _tx_thread_smp_protection.tx_thread_smp_protect_count++;
-@
- LDR r3, [r2, #12] @ Pickup ownership count
- ADD r3, r3, #1 @ Increment ownership count
- STR r3, [r2, #12] @ Store ownership count
- DMB
-
-#ifdef TX_MPCORE_DEBUG_ENABLE
- LSL r3, r1, #2 @ Build offset to array indexes
- LDR r4, =_tx_thread_current_ptr @ Pickup start of the current thread array
- ADD r4, r3, r4 @ Build index into the current thread array
- LDR r3, [r4] @ Pickup current thread for this core
- STR r3, [r2, #4] @ Save current thread pointer
- STR LR, [r2, #16] @ Save caller's return address
- STR r0, [r2, #20] @ Save CPSR
-#endif
-
- .endm
-
- .macro _tx_thread_smp_protect_remove_from_front_of_list
-@
-@ /* Remove ourselves from the list. */
-@ _tx_thread_smp_protect_wait_list[_tx_thread_smp_protect_wait_list_head++] = 0xFFFFFFFF;
-@
- MOV r3, #0xFFFFFFFF @ Build the invalid core value
- LDR r4, =_tx_thread_smp_protect_wait_list_head @ Get the address of the head
- LDR r5, [r4] @ Get the value of the head
- LDR r6, =_tx_thread_smp_protect_wait_list @ Get the address of the list
- STR r3, [r6, r5, LSL #2] @ Store the invalid core value
- ADD r5, r5, #1 @ Increment the head
-@
-@ /* Did we wrap? */
-@ if (_tx_thread_smp_protect_wait_list_head == TX_THREAD_SMP_MAX_CORES + 1)
-@ {
-@
- LDR r3, =_tx_thread_smp_protect_wait_list_size @ Load address of core list size
- LDR r3, [r3] @ Load the max cores value
- CMP r5, r3 @ Compare the head to it
- BNE _store_new_head\@ @ Are we at the max?
-@
-@ _tx_thread_smp_protect_wait_list_head = 0;
-@
- EOR r5, r5, r5 @ We're at the max. Set it to zero
-@
-@ }
-@
-_store_new_head\@:
-
- STR r5, [r4] @ Store the new head
-@
-@ /* We have the lock! */
-@ return;
-@
- .endm
-
-
- .macro _tx_thread_smp_protect_wait_list_lock_get
-@VOID _tx_thread_smp_protect_wait_list_lock_get()
-@{
-@ /* We do this until we have the lock. */
-@ while (1)
-@ {
-@
-_tx_thread_smp_protect_wait_list_lock_get__try_to_get_lock\@:
-@
-@ /* Is the list lock available? */
-@ _tx_thread_smp_protect_wait_list_lock_protect_in_force = load_exclusive(&_tx_thread_smp_protect_wait_list_lock_protect_in_force);
-@
- LDR r1, =_tx_thread_smp_protect_wait_list_lock_protect_in_force
- LDREX r2, [r1] @ Pickup the protection flag
-@
-@ if (protect_in_force == 0)
-@ {
-@
- CMP r2, #0
- BNE _tx_thread_smp_protect_wait_list_lock_get__try_to_get_lock\@ @ No, protection not available
-@
-@ /* Try to get the list. */
-@ int status = store_exclusive(&_tx_thread_smp_protect_wait_list_lock_protect_in_force, 1);
-@
- MOV r2, #1 @ Build lock value
- STREX r3, r2, [r1] @ Attempt to get the protection
-@
-@ if (status == SUCCESS)
-@
- CMP r3, #0
- BNE _tx_thread_smp_protect_wait_list_lock_get__try_to_get_lock\@ @ Did it fail? If so, try again.
-@
-@ /* We have the lock! */
-@ return;
-@
- .endm
-
-
- .macro _tx_thread_smp_protect_wait_list_add
-@VOID _tx_thread_smp_protect_wait_list_add(UINT new_core)
-@{
-@
-@ /* We're about to modify the list, so get the list lock. */
-@ _tx_thread_smp_protect_wait_list_lock_get();
-@
- PUSH {r1-r2}
-
- _tx_thread_smp_protect_wait_list_lock_get
-
- POP {r1-r2}
-@
-@ /* Add this core. */
-@ _tx_thread_smp_protect_wait_list[_tx_thread_smp_protect_wait_list_tail++] = new_core;
-@
- LDR r3, =_tx_thread_smp_protect_wait_list_tail @ Get the address of the tail
- LDR r4, [r3] @ Get the value of tail
- LDR r5, =_tx_thread_smp_protect_wait_list @ Get the address of the list
- STR r1, [r5, r4, LSL #2] @ Store the new core value
- ADD r4, r4, #1 @ Increment the tail
-@
-@ /* Did we wrap? */
-@ if (_tx_thread_smp_protect_wait_list_tail == _tx_thread_smp_protect_wait_list_size)
-@ {
-@
- LDR r5, =_tx_thread_smp_protect_wait_list_size @ Load max cores address
- LDR r5, [r5] @ Load max cores value
- CMP r4, r5 @ Compare max cores to tail
- BNE _tx_thread_smp_protect_wait_list_add__no_wrap\@ @ Did we wrap?
-@
-@ _tx_thread_smp_protect_wait_list_tail = 0;
-@
- MOV r4, #0
-@
-@ }
-@
-_tx_thread_smp_protect_wait_list_add__no_wrap\@:
-
- STR r4, [r3] @ Store the new tail value.
-@
-@ /* Release the list lock. */
-@ _tx_thread_smp_protect_wait_list_lock_protect_in_force = 0;
-@
- MOV r3, #0 @ Build lock value
- LDR r4, =_tx_thread_smp_protect_wait_list_lock_protect_in_force
- STR r3, [r4] @ Store the new value
-
- .endm
-
-
- .macro _tx_thread_smp_protect_wait_list_remove
-@VOID _tx_thread_smp_protect_wait_list_remove(UINT core)
-@{
-@
-@ /* Get the core index. */
-@ UINT core_index;
-@ for (core_index = 0;; core_index++)
-@
- EOR r1, r1, r1 @ Clear for 'core_index'
- LDR r2, =_tx_thread_smp_protect_wait_list @ Get the address of the list
-@
-@ {
-@
-_tx_thread_smp_protect_wait_list_remove__check_cur_core\@:
-@
-@ /* Is this the core? */
-@ if (_tx_thread_smp_protect_wait_list[core_index] == core)
-@ {
-@ break;
-@
- LDR r3, [r2, r1, LSL #2] @ Get the value at the current index
- CMP r3, r10 @ Did we find the core?
- BEQ _tx_thread_smp_protect_wait_list_remove__found_core\@
-@
-@ }
-@
- ADD r1, r1, #1 @ Increment cur index
- B _tx_thread_smp_protect_wait_list_remove__check_cur_core\@ @ Restart the loop
-@
-@ }
-@
-_tx_thread_smp_protect_wait_list_remove__found_core\@:
-@
-@ /* We're about to modify the list. Get the lock. We need the lock because another
-@ core could be simultaneously adding (a core is simultaneously trying to get
-@ the inter-core lock) or removing (a core is simultaneously being preempted,
-@ like what is currently happening). */
-@ _tx_thread_smp_protect_wait_list_lock_get();
-@
- PUSH {r1}
-
- _tx_thread_smp_protect_wait_list_lock_get
-
- POP {r1}
-@
-@ /* We remove by shifting. */
-@ while (core_index != _tx_thread_smp_protect_wait_list_tail)
-@ {
-@
-_tx_thread_smp_protect_wait_list_remove__compare_index_to_tail\@:
-
- LDR r2, =_tx_thread_smp_protect_wait_list_tail @ Load tail address
- LDR r2, [r2] @ Load tail value
- CMP r1, r2 @ Compare cur index and tail
- BEQ _tx_thread_smp_protect_wait_list_remove__removed\@
-@
-@ UINT next_index = core_index + 1;
-@
- MOV r2, r1 @ Move current index to next index register
- ADD r2, r2, #1 @ Add 1
-@
-@ if (next_index == _tx_thread_smp_protect_wait_list_size)
-@ {
-@
- LDR r3, =_tx_thread_smp_protect_wait_list_size
- LDR r3, [r3]
- CMP r2, r3
- BNE _tx_thread_smp_protect_wait_list_remove__next_index_no_wrap\@
-@
-@ next_index = 0;
-@
- MOV r2, #0
-@
-@ }
-@
-_tx_thread_smp_protect_wait_list_remove__next_index_no_wrap\@:
-@
-@ list_cores[core_index] = list_cores[next_index];
-@
- LDR r0, =_tx_thread_smp_protect_wait_list @ Get the address of the list
- LDR r3, [r0, r2, LSL #2] @ Get the value at the next index
- STR r3, [r0, r1, LSL #2] @ Store the value at the current index
-@
-@ core_index = next_index;
-@
- MOV r1, r2
-
- B _tx_thread_smp_protect_wait_list_remove__compare_index_to_tail\@
-@
-@ }
-@
-_tx_thread_smp_protect_wait_list_remove__removed\@:
-@
-@ /* Now update the tail. */
-@ if (_tx_thread_smp_protect_wait_list_tail == 0)
-@ {
-@
- LDR r0, =_tx_thread_smp_protect_wait_list_tail @ Load tail address
- LDR r1, [r0] @ Load tail value
- CMP r1, #0
- BNE _tx_thread_smp_protect_wait_list_remove__tail_not_zero\@
-@
-@ _tx_thread_smp_protect_wait_list_tail = _tx_thread_smp_protect_wait_list_size;
-@
- LDR r2, =_tx_thread_smp_protect_wait_list_size
- LDR r1, [r2]
-@
-@ }
-@
-_tx_thread_smp_protect_wait_list_remove__tail_not_zero\@:
-@
-@ _tx_thread_smp_protect_wait_list_tail--;
-@
- SUB r1, r1, #1
- STR r1, [r0] @ Store new tail value
-@
-@ /* Release the list lock. */
-@ _tx_thread_smp_protect_wait_list_lock_protect_in_force = 0;
-@
- MOV r0, #0 @ Build lock value
- LDR r1, =_tx_thread_smp_protect_wait_list_lock_protect_in_force @ Load lock address
- STR r0, [r1] @ Store the new value
-@
-@ /* We're no longer waiting. Note that this should be zero since, again,
-@ this function is only called when a thread preemption is occurring. */
-@ _tx_thread_smp_protect_wait_counts[core]--;
-@
- LDR r1, =_tx_thread_smp_protect_wait_counts @ Load wait list counts
- LDR r2, [r1, r10, LSL #2] @ Load waiting value
- SUB r2, r2, #1 @ Subtract 1
- STR r2, [r1, r10, LSL #2] @ Store new waiting value
-
- .endm
-
diff --git a/ports_smp/cortex_a7_smp/gnu/src/tx_thread_smp_time_get.S b/ports_smp/cortex_a7_smp/gnu/src/tx_thread_smp_time_get.S
index 067f50d8..e869c0e7 100644
--- a/ports_smp/cortex_a7_smp/gnu/src/tx_thread_smp_time_get.S
+++ b/ports_smp/cortex_a7_smp/gnu/src/tx_thread_smp_time_get.S
@@ -1,5 +1,6 @@
@/***************************************************************************
@ * Copyright (c) 2024 Microsoft Corporation
+@ * Copyright (c) 2026-present Eclipse ThreadX contributors
@ *
@ * This program and the accompanying materials are made available under the
@ * terms of the MIT License which is available at
@@ -8,6 +9,7 @@
@ * SPDX-License-Identifier: MIT
@ **************************************************************************/
@
+@ Portions of this file were generated with AI assistance.
@
@/**************************************************************************/
@/**************************************************************************/
@@ -70,8 +72,7 @@
.type _tx_thread_smp_time_get,function
_tx_thread_smp_time_get:
- MRC p15, 4, r0, c15, c0, 0 @ Read periph base address
- LDR r0, [r0, #0x604] @ Read count register
+ MRRC p15, 0, r0, r1, c14 @ Read generic timer physical count
#ifdef __THUMB_INTERWORK
BX lr @ Return to caller
@@ -79,4 +80,3 @@ _tx_thread_smp_time_get:
MOV pc, lr @ Return to caller
#endif
-
diff --git a/ports_smp/cortex_a7_smp/gnu/src/tx_thread_smp_unprotect.s b/ports_smp/cortex_a7_smp/gnu/src/tx_thread_smp_unprotect.S
index 5b939a05..66c6689c 100644
--- a/ports_smp/cortex_a7_smp/gnu/src/tx_thread_smp_unprotect.s
+++ b/ports_smp/cortex_a7_smp/gnu/src/tx_thread_smp_unprotect.S
@@ -1,5 +1,6 @@
@/***************************************************************************
@ * Copyright (c) 2024 Microsoft Corporation
+@ * 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
@@ -7,6 +8,7 @@
@ *
@ * SPDX-License-Identifier: MIT
@ **************************************************************************/
+@ Portions of this file were generated with AI assistance.
@
@
@/**************************************************************************/
@@ -33,7 +35,6 @@
.global _tx_thread_current_ptr
.global _tx_thread_smp_protection
.global _tx_thread_preempt_disable
- .global _tx_thread_smp_protect_wait_counts
.arm
.text
@@ -105,10 +106,6 @@ _tx_thread_smp_unprotect:
CMP r3, #0 @ Is the preempt disable flag set?
BNE _still_protected @ Yes, skip the protection release
- LDR r2,=_tx_thread_smp_protect_wait_counts @ Build build address of wait counts
- LDR r3, [r2, r1, LSL #2] @ Pickup wait list value
- CMP r3, #0 @ Are any entities on this core waiting?
- BNE _still_protected @ Yes, skip the protection release
LDR r2,=_tx_thread_smp_protection @ Build address of protection structure
MOV r3, #0xFFFFFFFF @ Build invalid value
diff --git a/ports_smp/cortex_a7_smp/gnu/src/tx_thread_system_return.S b/ports_smp/cortex_a7_smp/gnu/src/tx_thread_system_return.S
index 98e64ad1..7beaf661 100644
--- a/ports_smp/cortex_a7_smp/gnu/src/tx_thread_system_return.S
+++ b/ports_smp/cortex_a7_smp/gnu/src/tx_thread_system_return.S
@@ -1,5 +1,6 @@
@/***************************************************************************
@ * Copyright (c) 2024 Microsoft Corporation
+@ * Copyright (c) 2026-present Eclipse ThreadX contributors
@ *
@ * This program and the accompanying materials are made available under the
@ * terms of the MIT License which is available at
@@ -8,6 +9,7 @@
@ * SPDX-License-Identifier: MIT
@ **************************************************************************/
@
+@ Portions of this file were generated with AI assistance.
@
@/**************************************************************************/
@/**************************************************************************/
@@ -134,9 +136,10 @@ _tx_skip_solicited_vfp_save:
ADD r2, r2, r12 @ Build index into time-slice array
LDR r1, [r2, #0] @ Pickup current time slice
@
-@ /* Save current stack and switch to system stack. */
+@ /* Save the current stack pointer in the thread's control block. The
+@ scheduler runs on this core's banked SVC mode stack, which the startup
+@ code set up, so there is no stack switch to perform. */
@ _tx_thread_current_ptr[core] -> tx_thread_stack_ptr = sp;
-@ sp = _tx_thread_system_stack_ptr[core];
@
STR sp, [r0, #8] @ Save thread stack pointer
@
diff --git a/ports_smp/cortex_a7_smp/gnu/src/tx_thread_vectored_context_save.S b/ports_smp/cortex_a7_smp/gnu/src/tx_thread_vectored_context_save.S
index 0d8aab55..ee9ca1c7 100644
--- a/ports_smp/cortex_a7_smp/gnu/src/tx_thread_vectored_context_save.S
+++ b/ports_smp/cortex_a7_smp/gnu/src/tx_thread_vectored_context_save.S
@@ -1,5 +1,6 @@
@/***************************************************************************
@ * Copyright (c) 2024 Microsoft Corporation
+@ * Copyright (c) 2026-present Eclipse ThreadX contributors
@ *
@ * This program and the accompanying materials are made available under the
@ * terms of the MIT License which is available at
@@ -8,6 +9,7 @@
@ * SPDX-License-Identifier: MIT
@ **************************************************************************/
@
+@ Portions of this file were generated with AI assistance.
@
@/**************************************************************************/
@/**************************************************************************/
@@ -145,11 +147,11 @@ __tx_thread_not_nested_save:
@
@ /* Note: Minimal context of interrupted thread is already saved. */
@
-@ /* Save the current stack pointer in the thread's control block. */
-@ _tx_thread_current_ptr[core] -> tx_thread_stack_ptr = sp;
-@
-@ /* Switch to the system stack. */
-@ sp = _tx_thread_system_stack_ptr[core];
+@ /* This routine runs in IRQ mode on this core's banked IRQ stack, which
+@ serves as the system stack on this architecture, so there is no stack
+@ switch to perform here. The thread's stack pointer is saved in its
+@ control block by _tx_thread_context_restore, and only when the
+@ interrupt results in preemption. */
@
MOV r10, #0 @ Clear stack limit
diff --git a/ports_smp/cortex_a9_smp/ac5/inc/tx_port.h b/ports_smp/cortex_a9_smp/ac5/inc/tx_port.h
index 1f2ab286..b36a314f 100644
--- a/ports_smp/cortex_a9_smp/ac5/inc/tx_port.h
+++ b/ports_smp/cortex_a9_smp/ac5/inc/tx_port.h
@@ -393,7 +393,7 @@ void tx_thread_vfp_disable(void);
#ifdef TX_THREAD_INIT
CHAR _tx_version_id[] =
- "(c) 2024 Microsoft Corp. (c) 2026-present Eclipse ThreadX contributors. * ThreadX SMP/Cortex-A9/AC5 Version Version 6.5.1.202602a *";
+ "(c) 2024 Microsoft Corp. (c) 2026-present Eclipse ThreadX contributors. * ThreadX SMP/Cortex-A9/AC5 Version Version 6.5.2.202603 *";
#else
extern CHAR _tx_version_id[];
#endif
diff --git a/ports_smp/cortex_a9_smp/ac5/src/tx_thread_context_restore.s b/ports_smp/cortex_a9_smp/ac5/src/tx_thread_context_restore.s
index b6c179cd..4451091b 100644
--- a/ports_smp/cortex_a9_smp/ac5/src/tx_thread_context_restore.s
+++ b/ports_smp/cortex_a9_smp/ac5/src/tx_thread_context_restore.s
@@ -1,5 +1,6 @@
;/***************************************************************************
; * Copyright (c) 2024 Microsoft Corporation
+; * 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
@@ -7,6 +8,7 @@
; *
; * SPDX-License-Identifier: MIT
; **************************************************************************/
+; Portions of this file were generated with AI assistance.
;
;
;/**************************************************************************/
@@ -29,8 +31,6 @@
;#include "tx_thread.h"
;#include "tx_timer.h"
;
-;/* Include macros for modifying the wait list. */
-#include "tx_thread_smp_protection_wait_list_macros.h"
IF :DEF:TX_ENABLE_FIQ_SUPPORT
DISABLE_INTS EQU 0xC0 ; Disable IRQ & FIQ interrupts
@@ -51,11 +51,6 @@ SVC_MODE EQU 0x93 ; SVC mode
IMPORT _tx_thread_preempt_disable
IMPORT _tx_timer_interrupt_active
IMPORT _tx_thread_smp_protection
- IMPORT _tx_thread_smp_protect_wait_counts
- IMPORT _tx_thread_smp_protect_wait_list
- IMPORT _tx_thread_smp_protect_wait_list_lock_protect_in_force
- IMPORT _tx_thread_smp_protect_wait_list_tail
- IMPORT _tx_thread_smp_protect_wait_list_size
IF :DEF:TX_ENABLE_EXECUTION_CHANGE_NOTIFY
IMPORT _tx_execution_isr_exit
ENDIF
@@ -196,77 +191,6 @@ __tx_thread_no_preempt_restore
; {
;
__tx_thread_preempt_restore
-;
-; /* Was the thread being preempted waiting for the lock? */
-; if (_tx_thread_smp_protect_wait_counts[this_core] != 0)
-; {
-;
- LDR r1, =_tx_thread_smp_protect_wait_counts ; Load waiting count list
- LDR r2, [r1, r10, LSL #2] ; Load waiting value for this core
- CMP r2, #0
- BEQ _nobody_waiting_for_lock ; Is the core waiting for the lock?
-;
-; /* Do we not have the lock? This means the ISR never got the inter-core lock. */
-; if (_tx_thread_smp_protection.tx_thread_smp_protect_owned != this_core)
-; {
-;
- LDR r1, =_tx_thread_smp_protection ; Load address of protection structure
- LDR r2, [r1, #8] ; Pickup the owning core
- CMP r10, r2 ; Compare our core to the owning core
- BEQ _this_core_has_lock ; Do we have the lock?
-;
-; /* We don't have the lock. This core should be in the list. Remove it. */
-; _tx_thread_smp_protect_wait_list_remove(this_core);
-;
- MOV r0, r10 ; Move the core ID to r0 for the macro
-macro_call0 _tx_thread_smp_protect_wait_list_remove ; Call macro to remove core from the list
- B _nobody_waiting_for_lock ; Leave
-;
-; }
-; else
-; {
-; /* We have the lock. This means the ISR got the inter-core lock, but
-; never released it because it saw that there was someone waiting.
-; Note this core is not in the list. */
-;
-_this_core_has_lock
-;
-; /* We're no longer waiting. Note that this should be zero since this happens during thread preemption. */
-; _tx_thread_smp_protect_wait_counts[core]--;
-;
- LDR r1, =_tx_thread_smp_protect_wait_counts ; Load waiting count list
- LDR r2, [r1, r10, LSL #2] ; Load waiting value for this core
- SUB r2, r2, #1 ; Decrement waiting value. Should be zero now
- STR r2, [r1, r10, LSL #2] ; Store new waiting value
-;
-; /* Now release the inter-core lock. */
-;
-; /* Set protected core as invalid. */
-; _tx_thread_smp_protection.tx_thread_smp_protect_core = 0xFFFFFFFF;
-;
- LDR r1, =_tx_thread_smp_protection ; Load address of protection structure
- MOV r2, #0xFFFFFFFF ; Build invalid value
- STR r2, [r1, #8] ; Mark the protected core as invalid
- DMB ; Ensure that accesses to shared resource have completed
-;
-; /* Release protection. */
-; _tx_thread_smp_protection.tx_thread_smp_protect_in_force = 0;
-;
- MOV r2, #0 ; Build release protection value
- STR r2, [r1, #0] ; Release the protection
- DSB ISH ; To ensure update of the protection occurs before other CPUs awake
-;
-; /* Wake up waiting processors. Note interrupts are already enabled. */
-;
- IF :DEF:TX_ENABLE_WFE
- SEV ; Send event to other CPUs
- ENDIF
-;
-; }
-; }
-;
-
-_nobody_waiting_for_lock
LDMIA sp!, {r3, r10, r12, lr} ; Recover temporarily saved registers
MOV r1, lr ; Save lr (point of interrupt)
diff --git a/ports_smp/cortex_a9_smp/ac5/src/tx_thread_context_save.s b/ports_smp/cortex_a9_smp/ac5/src/tx_thread_context_save.s
index a0e2a5e6..9c047716 100644
--- a/ports_smp/cortex_a9_smp/ac5/src/tx_thread_context_save.s
+++ b/ports_smp/cortex_a9_smp/ac5/src/tx_thread_context_save.s
@@ -1,5 +1,6 @@
;/***************************************************************************
; * Copyright (c) 2024 Microsoft Corporation
+; * Copyright (c) 2026-present Eclipse ThreadX contributors
; *
; * This program and the accompanying materials are made available under the
; * terms of the MIT License which is available at
@@ -8,6 +9,7 @@
; * SPDX-License-Identifier: MIT
; **************************************************************************/
;
+; Portions of this file were generated with AI assistance.
;
;/**************************************************************************/
;/**************************************************************************/
@@ -145,11 +147,11 @@ __tx_thread_not_nested_save
BEQ __tx_thread_idle_system_save ; If so, interrupt occurred in
; scheduling loop - nothing needs saving!
;
-; /* Save the current stack pointer in the thread's control block. */
-; _tx_thread_current_ptr[core] -> tx_thread_stack_ptr = sp;
-;
-; /* Switch to the system stack. */
-; sp = _tx_thread_system_stack_ptr;
+; /* This routine runs in IRQ mode on this core's banked IRQ stack, which
+; serves as the system stack on this architecture, so there is no stack
+; switch to perform here. The thread's stack pointer is saved in its
+; control block by _tx_thread_context_restore, and only when the
+; interrupt results in preemption. */
;
MOV r10, #0 ; Clear stack limit
diff --git a/ports_smp/cortex_a9_smp/ac5/src/tx_thread_schedule.s b/ports_smp/cortex_a9_smp/ac5/src/tx_thread_schedule.s
index 63e7492c..45298ff3 100644
--- a/ports_smp/cortex_a9_smp/ac5/src/tx_thread_schedule.s
+++ b/ports_smp/cortex_a9_smp/ac5/src/tx_thread_schedule.s
@@ -1,5 +1,6 @@
;/***************************************************************************
; * Copyright (c) 2024 Microsoft Corporation
+; * 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
@@ -8,6 +9,8 @@
; * SPDX-License-Identifier: MIT
; **************************************************************************/
;
+; Portions of this file were generated with AI assistance.
+;
;
;/**************************************************************************/
;/**************************************************************************/
@@ -163,6 +166,7 @@ _tx_thread_ready_for_execution
LDR r2, =_tx_thread_current_ptr ; Pickup address of current thread
ADD r2, r2, r12 ; Build index into the current thread array
STR r0, [r2, #0] ; Setup current thread pointer
+ DMB ; Ensure the current thread pointer write completes
;
; /* In the time between reading the execute pointer and assigning
; it to the current pointer, the execute pointer was changed by
diff --git a/ports_smp/cortex_a9_smp/ac5/src/tx_thread_smp_protect.s b/ports_smp/cortex_a9_smp/ac5/src/tx_thread_smp_protect.s
index 1f2330d9..fe92cb92 100644
--- a/ports_smp/cortex_a9_smp/ac5/src/tx_thread_smp_protect.s
+++ b/ports_smp/cortex_a9_smp/ac5/src/tx_thread_smp_protect.s
@@ -1,5 +1,6 @@
;/***************************************************************************
; * Copyright (c) 2024 Microsoft Corporation
+; * 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
@@ -7,6 +8,7 @@
; *
; * SPDX-License-Identifier: MIT
; **************************************************************************/
+; Portions of this file were generated with AI assistance.
;
;
;/**************************************************************************/
@@ -31,17 +33,9 @@
;
;
-;/* Include macros for modifying the wait list. */
-#include "tx_thread_smp_protection_wait_list_macros.h"
IMPORT _tx_thread_current_ptr
IMPORT _tx_thread_smp_protection
- IMPORT _tx_thread_smp_protect_wait_counts
- IMPORT _tx_thread_smp_protect_wait_list
- IMPORT _tx_thread_smp_protect_wait_list_lock_protect_in_force
- IMPORT _tx_thread_smp_protect_wait_list_head
- IMPORT _tx_thread_smp_protect_wait_list_tail
- IMPORT _tx_thread_smp_protect_wait_list_size
AREA ||.text||, CODE, READONLY
PRESERVE8
@@ -83,11 +77,9 @@ _tx_thread_smp_protect
;VOID _tx_thread_smp_protect(VOID)
;{
;
- PUSH {r4-r6} ; Save registers we'll be using
-;
; /* Disable interrupts so we don't get preempted. */
;
- MRS r0, CPSR ; Pickup current CPSR
+ MRS r3, CPSR ; Pickup current CPSR
IF :DEF:TX_ENABLE_FIQ_SUPPORT
CPSID if ; Disable IRQ and FIQ interrupts
@@ -95,266 +87,93 @@ _tx_thread_smp_protect
CPSID i ; Disable IRQ interrupts
ENDIF
;
+; /* Pickup the CPU ID. */
+;
+ MRC p15, 0, r2, c0, c0, 5 ; Read CPU ID register
+ AND r2, r2, #0x03 ; Mask off, leaving the CPU ID field
+;
; /* Do we already have protection? */
; if (this_core == _tx_thread_smp_protection.tx_thread_smp_protect_core)
; {
;
- MRC p15, 0, r1, c0, c0, 5 ; Read CPU ID register
- AND r1, r1, #0x03 ; Mask off, leaving the CPU ID field
- LDR r2, =_tx_thread_smp_protection ; Build address to protection structure
- LDR r3, [r2, #8] ; Pickup the owning core
- CMP r1, r3 ; Is it not this core?
- BNE _protection_not_owned ; No, the protection is not already owned
-;
-; /* We already have protection. */
-;
-; /* Increment the protection count. */
-; _tx_thread_smp_protection.tx_thread_smp_protect_count++;
+ LDR r0, =_tx_thread_smp_protection ; Build address to protection structure
+ LDR r1, [r0, #8] ; Pickup the owning core
+ CMP r1, r2 ; Is it this core?
+ BEQ _owned ; Yes, the protection is already owned
;
- LDR r3, [r2, #12] ; Pickup ownership count
- ADD r3, r3, #1 ; Increment ownership count
- STR r3, [r2, #12] ; Store ownership count
- DMB
-
- B _return
-
-_protection_not_owned
+; }
;
; /* Is the lock available? */
; if (_tx_thread_smp_protection.tx_thread_smp_protect_in_force == 0)
; {
;
- LDREX r3, [r2, #0] ; Pickup the protection flag
- CMP r3, #0
- BNE _start_waiting ; No, protection not available
-;
-; /* Is the list empty? */
-; if (_tx_thread_smp_protect_wait_list_head == _tx_thread_smp_protect_wait_list_tail)
-; {
-;
- LDR r3, =_tx_thread_smp_protect_wait_list_head
- LDR r3, [r3]
- LDR r4, =_tx_thread_smp_protect_wait_list_tail
- LDR r4, [r4]
- CMP r3, r4
- BNE _list_not_empty
-;
-; /* Try to get the lock. */
-; if (write_exclusive(&_tx_thread_smp_protection.tx_thread_smp_protect_in_force, 1) == SUCCESS)
-; {
-;
- MOV r3, #1 ; Build lock value
- STREX r4, r3, [r2, #0] ; Attempt to get the protection
- CMP r4, #0
- BNE _start_waiting ; Did it fail?
-;
-; /* We got the lock! */
-; _tx_thread_smp_protect_lock_got();
-;
- DMB ; Ensure write to protection finishes
-macro_call0 _tx_thread_smp_protect_lock_got ; Call the lock got function
-
- B _return
-
-_list_not_empty
-;
-; /* Are we at the front of the list? */
-; if (this_core == _tx_thread_smp_protect_wait_list[_tx_thread_smp_protect_wait_list_head])
-; {
-;
- LDR r3, =_tx_thread_smp_protect_wait_list_head ; Get the address of the head
- LDR r3, [r3] ; Get the value of the head
- LDR r4, =_tx_thread_smp_protect_wait_list ; Get the address of the list
- LDR r4, [r4, r3, LSL #2] ; Get the value at the head index
-
- CMP r1, r4
- BNE _start_waiting
-;
-; /* Is the lock still available? */
-; if (_tx_thread_smp_protection.tx_thread_smp_protect_in_force == 0)
-; {
-;
- LDR r3, [r2, #0] ; Pickup the protection flag
- CMP r3, #0
- BNE _start_waiting ; No, protection not available
-;
-; /* Get the lock. */
-; _tx_thread_smp_protection.tx_thread_smp_protect_in_force = 1;
-;
- MOV r3, #1 ; Build lock value
- STR r3, [r2, #0] ; Store lock value
- DMB ;
-;
-; /* Got the lock. */
-; _tx_thread_smp_protect_lock_got();
-;
-macro_call1 _tx_thread_smp_protect_lock_got
-;
-; /* Remove this core from the wait list. */
-; _tx_thread_smp_protect_remove_from_front_of_list();
-;
-macro_call2 _tx_thread_smp_protect_remove_from_front_of_list
-
- B _return
-
-_start_waiting
-;
-; /* For one reason or another, we didn't get the lock. */
-;
-; /* Increment wait count. */
-; _tx_thread_smp_protect_wait_counts[this_core]++;
-;
- LDR r3, =_tx_thread_smp_protect_wait_counts ; Load wait list counts
- LDR r4, [r3, r1, LSL #2] ; Load waiting value for this core
- ADD r4, r4, #1 ; Increment wait value
- STR r4, [r3, r1, LSL #2] ; Store new wait value
-;
-; /* Have we not added ourselves to the list yet? */
-; if (_tx_thread_smp_protect_wait_counts[this_core] == 1)
-; {
-;
- CMP r4, #1
- BNE _already_in_list0 ; Is this core already waiting?
-;
-; /* Add ourselves to the list. */
-; _tx_thread_smp_protect_wait_list_add(this_core);
-;
-macro_call3 _tx_thread_smp_protect_wait_list_add ; Call macro to add ourselves to the list
+ LDREX r1, [r0] ; Pickup the protection flag
+ CMP r1, #0 ; Is it available?
+ BEQ _get_protection ; Yes, attempt to get the protection
;
; }
;
-_already_in_list0
-;
-; /* Restore interrupts. */
+; /* The protection is held elsewhere. Restore interrupts so this core can be
+; preempted while it waits, then try the whole sequence again. */
;
- MSR CPSR_c, r0 ; Restore CPSR
+ MSR CPSR_c, r3 ; Restore CPSR
IF :DEF:TX_ENABLE_WFE
WFE ; Go into standby
ENDIF
-;
-; /* We do this until we have the lock. */
-; while (1)
-; {
-;
-_try_to_get_lock
-;
-; /* Disable interrupts so we don't get preempted. */
-;
- IF :DEF:TX_ENABLE_FIQ_SUPPORT
- CPSID if ; Disable IRQ and FIQ interrupts
- ELSE
- CPSID i ; Disable IRQ interrupts
- ENDIF
+ B _tx_thread_smp_protect ; On waking, restart the protection attempt
- MRC p15, 0, r1, c0, c0, 5 ; Read CPU ID register
- AND r1, r1, #0x03 ; Mask off, leaving the CPU ID field
+_get_protection
;
-; /* Do we already have protection? */
-; if (this_core == _tx_thread_smp_protection.tx_thread_smp_protect_core)
+; /* Try to get the lock. */
+; if (write_exclusive(&_tx_thread_smp_protection.tx_thread_smp_protect_in_force, 1) == SUCCESS)
; {
;
- LDR r3, [r2, #8] ; Pickup the owning core
- CMP r3, r1 ; Is it this core?
- BEQ _got_lock_after_waiting ; Yes, the protection is already owned. This means
- ; an ISR preempted us and got protection
+ MOV r1, #1 ; Build lock value
+ STREX r2, r1, [r0] ; Attempt to get the protection
+ CMP r2, #0 ; Check whether the store succeeded (0 = success)
+ BEQ _got_protection ; Yes, we have the protection
;
; }
;
-; /* Are we at the front of the list? */
-; if (this_core == _tx_thread_smp_protect_wait_list[_tx_thread_smp_protect_wait_list_head])
-; {
+; /* Another core beat us to it. Restore interrupts and try again. */
;
- LDR r3, =_tx_thread_smp_protect_wait_list_head ; Get the address of the head
- LDR r3, [r3] ; Get the value of the head
- LDR r4, =_tx_thread_smp_protect_wait_list ; Get the address of the list
- LDR r4, [r4, r3, LSL #2] ; Get the value at the head index
+ MSR CPSR_c, r3 ; Restore CPSR
+ B _tx_thread_smp_protect ; Try the whole process again
- CMP r1, r4
- BNE _did_not_get_lock
-;
-; /* Is the lock still available? */
-; if (_tx_thread_smp_protection.tx_thread_smp_protect_in_force == 0)
-; {
-;
- LDR r3, [r2, #0] ; Pickup the protection flag
- CMP r3, #0
- BNE _did_not_get_lock ; No, protection not available
-;
-; /* Get the lock. */
-; _tx_thread_smp_protection.tx_thread_smp_protect_in_force = 1;
-;
- MOV r3, #1 ; Build lock value
- STR r3, [r2, #0] ; Store lock value
- DMB ;
+_got_protection
;
-; /* Got the lock. */
-; _tx_thread_smp_protect_lock_got();
+; /* Got the lock. Record the owning core. */
+; _tx_thread_smp_protection.tx_thread_smp_protect_core = this_core;
;
-macro_call4 _tx_thread_smp_protect_lock_got
-;
-; /* Remove this core from the wait list. */
-; _tx_thread_smp_protect_remove_from_front_of_list();
-;
-macro_call5 _tx_thread_smp_protect_remove_from_front_of_list
-
- B _got_lock_after_waiting
+ DMB ; Ensure the protection write completes before it is used
+ MRC p15, 0, r2, c0, c0, 5 ; Read CPU ID register
+ AND r2, r2, #0x03 ; Mask off, leaving the CPU ID field
+ STR r2, [r0, #8] ; Save the owning core
-_did_not_get_lock
-;
-; /* For one reason or another, we didn't get the lock. */
-;
-; /* Were we removed from the list? This can happen if we're a thread
-; and we got preempted. */
-; if (_tx_thread_smp_protect_wait_counts[this_core] == 0)
-; {
-;
- LDR r3, =_tx_thread_smp_protect_wait_counts ; Load wait list counts
- LDR r4, [r3, r1, LSL #2] ; Load waiting value for this core
- CMP r4, #0
- BNE _already_in_list1 ; Is this core already in the list?
-;
-; /* Add ourselves to the list. */
-; _tx_thread_smp_protect_wait_list_add(this_core);
-;
-macro_call6 _tx_thread_smp_protect_wait_list_add ; Call macro to add ourselves to the list
-;
-; /* Our waiting count was also reset when we were preempted. Increment it again. */
-; _tx_thread_smp_protect_wait_counts[this_core]++;
-;
- LDR r3, =_tx_thread_smp_protect_wait_counts ; Load wait list counts
- LDR r4, [r3, r1, LSL #2] ; Load waiting value for this core
- ADD r4, r4, #1 ; Increment wait value
- STR r4, [r3, r1, LSL #2] ; Store new wait value value
-;
-; }
-;
-_already_in_list1
-;
-; /* Restore interrupts and try again. */
-;
- MSR CPSR_c, r0 ; Restore CPSR
- IF :DEF:TX_ENABLE_WFE
- WFE ; Go into standby
+ IF :DEF:TX_MPCORE_DEBUG_ENABLE
+ LSL r2, r2, #2 ; Build offset to array indexes
+ LDR r1, =_tx_thread_current_ptr ; Pickup start of the current thread array
+ ADD r1, r1, r2 ; Build index into the current thread array
+ LDR r2, [r1] ; Pickup current thread for this core
+ STR r2, [r0, #4] ; Save current thread pointer
+ STR LR, [r0, #16] ; Save caller's return address
+ STR r3, [r0, #20] ; Save CPSR
ENDIF
- B _try_to_get_lock ; On waking, restart the protection attempt
-_got_lock_after_waiting
+_owned
;
-; /* We're no longer waiting. */
-; _tx_thread_smp_protect_wait_counts[this_core]--;
+; /* Increment the protection count. */
+; _tx_thread_smp_protection.tx_thread_smp_protect_count++;
;
- LDR r3, =_tx_thread_smp_protect_wait_counts ; Load waiting list
- LDR r4, [r3, r1, LSL #2] ; Load current wait value
- SUB r4, r4, #1 ; Decrement wait value
- STR r4, [r3, r1, LSL #2] ; Store new wait value value
+ LDR r1, [r0, #12] ; Pickup ownership count
+ ADD r1, r1, #1 ; Increment ownership count
+ STR r1, [r0, #12] ; Store new ownership count
+ DMB ;
+ MOV r0, r3 ; Return the previous CPSR
;
-; /* Restore link register and return. */
+;}
;
-_return
-
- POP {r4-r6} ; Restore registers
-
IF {INTER} = {TRUE}
BX lr ; Return to caller
ELSE
@@ -362,4 +181,3 @@ _return
ENDIF
END
-
diff --git a/ports_smp/cortex_a9_smp/ac5/src/tx_thread_smp_protection_wait_list_macros.h b/ports_smp/cortex_a9_smp/ac5/src/tx_thread_smp_protection_wait_list_macros.h
deleted file mode 100644
index fec51581..00000000
--- a/ports_smp/cortex_a9_smp/ac5/src/tx_thread_smp_protection_wait_list_macros.h
+++ /dev/null
@@ -1,314 +0,0 @@
-;/***************************************************************************
-; * Copyright (c) 2024 Microsoft Corporation
-; *
-; * 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.
-; *
-; * SPDX-License-Identifier: MIT
-; **************************************************************************/
-;
-;
-;/**************************************************************************/
-;/**************************************************************************/
-;/** */
-;/** ThreadX Component */
-;/** */
-;/** Thread - Low Level SMP Support */
-;/** */
-;/**************************************************************************/
-;/**************************************************************************/
-
- MACRO
-$label _tx_thread_smp_protect_lock_got
-;
-; /* Set the currently owned core. */
-; _tx_thread_smp_protection.tx_thread_smp_protect_core = this_core;
-;
- STR r1, [r2, #8] ; Store this core
-;
-; /* Increment the protection count. */
-; _tx_thread_smp_protection.tx_thread_smp_protect_count++;
-;
- LDR r3, [r2, #12] ; Pickup ownership count
- ADD r3, r3, #1 ; Increment ownership count
- STR r3, [r2, #12] ; Store ownership count
- DMB
-
- IF :DEF:TX_MPCORE_DEBUG_ENABLE
- LSL r3, r1, #2 ; Build offset to array indexes
- LDR r4, =_tx_thread_current_ptr ; Pickup start of the current thread array
- ADD r4, r3, r4 ; Build index into the current thread array
- LDR r3, [r4] ; Pickup current thread for this core
- STR r3, [r2, #4] ; Save current thread pointer
- STR LR, [r2, #16] ; Save caller's return address
- STR r0, [r2, #20] ; Save CPSR
- ENDIF
-
- MEND
-
- MACRO
-$label _tx_thread_smp_protect_remove_from_front_of_list
-;
-; /* Remove ourselves from the list. */
-; _tx_thread_smp_protect_wait_list[_tx_thread_smp_protect_wait_list_head++] = 0xFFFFFFFF;
-;
- MOV r3, #0xFFFFFFFF ; Build the invalid core value
- LDR r4, =_tx_thread_smp_protect_wait_list_head ; Get the address of the head
- LDR r5, [r4] ; Get the value of the head
- LDR r6, =_tx_thread_smp_protect_wait_list ; Get the address of the list
- STR r3, [r6, r5, LSL #2] ; Store the invalid core value
- ADD r5, r5, #1 ; Increment the head
-;
-; /* Did we wrap? */
-; if (_tx_thread_smp_protect_wait_list_head == TX_THREAD_SMP_MAX_CORES + 1)
-; {
-;
- LDR r3, =_tx_thread_smp_protect_wait_list_size ; Load address of core list size
- LDR r3, [r3] ; Load the max cores value
- CMP r5, r3 ; Compare the head to it
- BNE $label._store_new_head ; Are we at the max?
-;
-; _tx_thread_smp_protect_wait_list_head = 0;
-;
- EOR r5, r5, r5 ; We're at the max. Set it to zero
-;
-; }
-;
-$label._store_new_head
-
- STR r5, [r4] ; Store the new head
-;
-; /* We have the lock! */
-; return;
-;
- MEND
-
-
- MACRO
-$label _tx_thread_smp_protect_wait_list_lock_get
-;VOID _tx_thread_smp_protect_wait_list_lock_get()
-;{
-; /* We do this until we have the lock. */
-; while (1)
-; {
-;
-$label._tx_thread_smp_protect_wait_list_lock_get__try_to_get_lock
-;
-; /* Is the list lock available? */
-; _tx_thread_smp_protect_wait_list_lock_protect_in_force = load_exclusive(&_tx_thread_smp_protect_wait_list_lock_protect_in_force);
-;
- LDR r1, =_tx_thread_smp_protect_wait_list_lock_protect_in_force
- LDREX r2, [r1] ; Pickup the protection flag
-;
-; if (protect_in_force == 0)
-; {
-;
- CMP r2, #0
- BNE $label._tx_thread_smp_protect_wait_list_lock_get__try_to_get_lock ; No, protection not available
-;
-; /* Try to get the list. */
-; int status = store_exclusive(&_tx_thread_smp_protect_wait_list_lock_protect_in_force, 1);
-;
- MOV r2, #1 ; Build lock value
- STREX r3, r2, [r1] ; Attempt to get the protection
-;
-; if (status == SUCCESS)
-;
- CMP r3, #0
- BNE $label._tx_thread_smp_protect_wait_list_lock_get__try_to_get_lock ; Did it fail? If so, try again.
-;
-; /* We have the lock! */
-; return;
-;
- MEND
-
-
- MACRO
-$label _tx_thread_smp_protect_wait_list_add
-;VOID _tx_thread_smp_protect_wait_list_add(UINT new_core)
-;{
-;
-; /* We're about to modify the list, so get the list lock. */
-; _tx_thread_smp_protect_wait_list_lock_get();
-;
- PUSH {r1-r2}
-
-$label _tx_thread_smp_protect_wait_list_lock_get
-
- POP {r1-r2}
-;
-; /* Add this core. */
-; _tx_thread_smp_protect_wait_list[_tx_thread_smp_protect_wait_list_tail++] = new_core;
-;
- LDR r3, =_tx_thread_smp_protect_wait_list_tail ; Get the address of the tail
- LDR r4, [r3] ; Get the value of tail
- LDR r5, =_tx_thread_smp_protect_wait_list ; Get the address of the list
- STR r1, [r5, r4, LSL #2] ; Store the new core value
- ADD r4, r4, #1 ; Increment the tail
-;
-; /* Did we wrap? */
-; if (_tx_thread_smp_protect_wait_list_tail == _tx_thread_smp_protect_wait_list_size)
-; {
-;
- LDR r5, =_tx_thread_smp_protect_wait_list_size ; Load max cores address
- LDR r5, [r5] ; Load max cores value
- CMP r4, r5 ; Compare max cores to tail
- BNE $label._tx_thread_smp_protect_wait_list_add__no_wrap ; Did we wrap?
-;
-; _tx_thread_smp_protect_wait_list_tail = 0;
-;
- MOV r4, #0
-;
-; }
-;
-$label._tx_thread_smp_protect_wait_list_add__no_wrap
-
- STR r4, [r3] ; Store the new tail value.
-;
-; /* Release the list lock. */
-; _tx_thread_smp_protect_wait_list_lock_protect_in_force = 0;
-;
- MOV r3, #0 ; Build lock value
- LDR r4, =_tx_thread_smp_protect_wait_list_lock_protect_in_force
- STR r3, [r4] ; Store the new value
-
- MEND
-
-
- MACRO
-$label _tx_thread_smp_protect_wait_list_remove
-;VOID _tx_thread_smp_protect_wait_list_remove(UINT core)
-;{
-;
-; /* Get the core index. */
-; UINT core_index;
-; for (core_index = 0;; core_index++)
-;
- EOR r1, r1, r1 ; Clear for 'core_index'
- LDR r2, =_tx_thread_smp_protect_wait_list ; Get the address of the list
-;
-; {
-;
-$label._tx_thread_smp_protect_wait_list_remove__check_cur_core
-;
-; /* Is this the core? */
-; if (_tx_thread_smp_protect_wait_list[core_index] == core)
-; {
-; break;
-;
- LDR r3, [r2, r1, LSL #2] ; Get the value at the current index
- CMP r3, r0 ; Did we find the core?
- BEQ $label._tx_thread_smp_protect_wait_list_remove__found_core
-;
-; }
-;
- ADD r1, r1, #1 ; Increment cur index
- B $label._tx_thread_smp_protect_wait_list_remove__check_cur_core ; Restart the loop
-;
-; }
-;
-$label._tx_thread_smp_protect_wait_list_remove__found_core
-;
-; /* We're about to modify the list. Get the lock. We need the lock because another
-; core could be simultaneously adding (a core is simultaneously trying to get
-; the inter-core lock) or removing (a core is simultaneously being preempted,
-; like what is currently happening). */
-; _tx_thread_smp_protect_wait_list_lock_get();
-;
- PUSH {r1}
-
-$label _tx_thread_smp_protect_wait_list_lock_get
-
- POP {r1}
-;
-; /* We remove by shifting. */
-; while (core_index != _tx_thread_smp_protect_wait_list_tail)
-; {
-;
-$label._tx_thread_smp_protect_wait_list_remove__compare_index_to_tail
-
- LDR r2, =_tx_thread_smp_protect_wait_list_tail ; Load tail address
- LDR r2, [r2] ; Load tail value
- CMP r1, r2 ; Compare cur index and tail
- BEQ $label._tx_thread_smp_protect_wait_list_remove__removed
-;
-; UINT next_index = core_index + 1;
-;
- MOV r2, r1 ; Move current index to next index register
- ADD r2, r2, #1 ; Add 1
-;
-; if (next_index == _tx_thread_smp_protect_wait_list_size)
-; {
-;
- LDR r3, =_tx_thread_smp_protect_wait_list_size
- LDR r3, [r3]
- CMP r2, r3
- BNE $label._tx_thread_smp_protect_wait_list_remove__next_index_no_wrap
-;
-; next_index = 0;
-;
- MOV r2, #0
-;
-; }
-;
-$label._tx_thread_smp_protect_wait_list_remove__next_index_no_wrap
-;
-; list_cores[core_index] = list_cores[next_index];
-;
- LDR r0, =_tx_thread_smp_protect_wait_list ; Get the address of the list
- LDR r3, [r0, r2, LSL #2] ; Get the value at the next index
- STR r3, [r0, r1, LSL #2] ; Store the value at the current index
-;
-; core_index = next_index;
-;
- MOV r1, r2
-
- B $label._tx_thread_smp_protect_wait_list_remove__compare_index_to_tail
-;
-; }
-;
-$label._tx_thread_smp_protect_wait_list_remove__removed
-;
-; /* Now update the tail. */
-; if (_tx_thread_smp_protect_wait_list_tail == 0)
-; {
-;
- LDR r0, =_tx_thread_smp_protect_wait_list_tail ; Load tail address
- LDR r1, [r0] ; Load tail value
- CMP r1, #0
- BNE $label._tx_thread_smp_protect_wait_list_remove__tail_not_zero
-;
-; _tx_thread_smp_protect_wait_list_tail = _tx_thread_smp_protect_wait_list_size;
-;
- LDR r2, =_tx_thread_smp_protect_wait_list_size
- LDR r1, [r2]
-;
-; }
-;
-$label._tx_thread_smp_protect_wait_list_remove__tail_not_zero
-;
-; _tx_thread_smp_protect_wait_list_tail--;
-;
- SUB r1, r1, #1
- STR r1, [r0] ; Store new tail value
-;
-; /* Release the list lock. */
-; _tx_thread_smp_protect_wait_list_lock_protect_in_force = 0;
-;
- MOV r0, #0 ; Build lock value
- LDR r1, =_tx_thread_smp_protect_wait_list_lock_protect_in_force ; Load lock address
- STR r0, [r1] ; Store the new value
-;
-; /* We're no longer waiting. Note that this should be zero since, again,
-; this function is only called when a thread preemption is occurring. */
-; _tx_thread_smp_protect_wait_counts[core]--;
-;
- MRC p15, 0, r0, c0, c0, 5 ; Read CPU ID register
- AND r0, r0, #0x03 ; Mask off, leaving the CPU ID field
- LDR r1, =_tx_thread_smp_protect_wait_counts ; Load wait list counts
- LDR r2, [r1, r0, LSL #2] ; Load waiting value
- SUB r2, r2, #1 ; Subtract 1
- STR r2, [r1, r0, LSL #2] ; Store new waiting value
- MEND
-
diff --git a/ports_smp/cortex_a9_smp/ac5/src/tx_thread_smp_time_get.s b/ports_smp/cortex_a9_smp/ac5/src/tx_thread_smp_time_get.s
index 5b67b283..9da21821 100644
--- a/ports_smp/cortex_a9_smp/ac5/src/tx_thread_smp_time_get.s
+++ b/ports_smp/cortex_a9_smp/ac5/src/tx_thread_smp_time_get.s
@@ -1,5 +1,6 @@
;/***************************************************************************
; * Copyright (c) 2024 Microsoft Corporation
+; * Copyright (c) 2026-present Eclipse ThreadX contributors
; *
; * This program and the accompanying materials are made available under the
; * terms of the MIT License which is available at
@@ -8,6 +9,7 @@
; * SPDX-License-Identifier: MIT
; **************************************************************************/
;
+; Portions of this file were generated with AI assistance.
;
;/**************************************************************************/
;/**************************************************************************/
@@ -69,7 +71,7 @@
_tx_thread_smp_time_get
MRC p15, 4, r0, c15, c0, 0 ; Read periph base address
- LDR r0, [r0, #0x604] ; Read count register
+ LDR r0, [r0, #0x200] ; Read global timer count low register
IF {INTER} = {TRUE}
BX lr ; Return to caller
@@ -78,4 +80,3 @@ _tx_thread_smp_time_get
ENDIF
END
-
diff --git a/ports_smp/cortex_a9_smp/ac5/src/tx_thread_smp_unprotect.s b/ports_smp/cortex_a9_smp/ac5/src/tx_thread_smp_unprotect.s
index ed3fae48..1b4b963a 100644
--- a/ports_smp/cortex_a9_smp/ac5/src/tx_thread_smp_unprotect.s
+++ b/ports_smp/cortex_a9_smp/ac5/src/tx_thread_smp_unprotect.s
@@ -1,5 +1,6 @@
;/***************************************************************************
; * Copyright (c) 2024 Microsoft Corporation
+; * 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
@@ -7,6 +8,7 @@
; *
; * SPDX-License-Identifier: MIT
; **************************************************************************/
+; Portions of this file were generated with AI assistance.
;
;
;/**************************************************************************/
@@ -33,7 +35,6 @@
IMPORT _tx_thread_current_ptr
IMPORT _tx_thread_smp_protection
IMPORT _tx_thread_preempt_disable
- IMPORT _tx_thread_smp_protect_wait_counts
AREA ||.text||, CODE, READONLY
PRESERVE8
@@ -103,10 +104,6 @@ _tx_thread_smp_unprotect
CMP r3, #0 ; Is the preempt disable flag set?
BNE _still_protected ; Yes, skip the protection release
- LDR r2,=_tx_thread_smp_protect_wait_counts ; Build build address of wait counts
- LDR r3, [r2, r1, LSL #2] ; Pickup wait list value
- CMP r3, #0 ; Are any entities on this core waiting?
- BNE _still_protected ; Yes, skip the protection release
LDR r2,=_tx_thread_smp_protection ; Build address of protection structure
MOV r3, #0xFFFFFFFF ; Build invalid value
diff --git a/ports_smp/cortex_a9_smp/ac5/src/tx_thread_system_return.s b/ports_smp/cortex_a9_smp/ac5/src/tx_thread_system_return.s
index f03fc6fe..485b0131 100644
--- a/ports_smp/cortex_a9_smp/ac5/src/tx_thread_system_return.s
+++ b/ports_smp/cortex_a9_smp/ac5/src/tx_thread_system_return.s
@@ -1,5 +1,6 @@
;/***************************************************************************
; * Copyright (c) 2024 Microsoft Corporation
+; * Copyright (c) 2026-present Eclipse ThreadX contributors
; *
; * This program and the accompanying materials are made available under the
; * terms of the MIT License which is available at
@@ -8,6 +9,7 @@
; * SPDX-License-Identifier: MIT
; **************************************************************************/
;
+; Portions of this file were generated with AI assistance.
;
;/**************************************************************************/
;/**************************************************************************/
@@ -132,9 +134,10 @@ _tx_skip_solicited_vfp_save
ADD r2, r2, r12 ; Build index into time-slice array
LDR r1, [r2, #0] ; Pickup current time slice
;
-; /* Save current stack and switch to system stack. */
+; /* Save the current stack pointer in the thread's control block. The
+; scheduler runs on this core's banked SVC mode stack, which the startup
+; code set up, so there is no stack switch to perform. */
; _tx_thread_current_ptr[core] -> tx_thread_stack_ptr = sp;
-; sp = _tx_thread_system_stack_ptr[core];
;
STR sp, [r0, #8] ; Save thread stack pointer
;
diff --git a/ports_smp/cortex_a9_smp/ac5/src/tx_thread_vectored_context_save.s b/ports_smp/cortex_a9_smp/ac5/src/tx_thread_vectored_context_save.s
index 8102e78b..26acf6e4 100644
--- a/ports_smp/cortex_a9_smp/ac5/src/tx_thread_vectored_context_save.s
+++ b/ports_smp/cortex_a9_smp/ac5/src/tx_thread_vectored_context_save.s
@@ -1,5 +1,6 @@
;/***************************************************************************
; * Copyright (c) 2024 Microsoft Corporation
+; * Copyright (c) 2026-present Eclipse ThreadX contributors
; *
; * This program and the accompanying materials are made available under the
; * terms of the MIT License which is available at
@@ -8,6 +9,7 @@
; * SPDX-License-Identifier: MIT
; **************************************************************************/
;
+; Portions of this file were generated with AI assistance.
;
;/**************************************************************************/
;/**************************************************************************/
@@ -143,11 +145,11 @@ __tx_thread_not_nested_save
;
; /* Note: Minimal context of interrupted thread is already saved. */
;
-; /* Save the current stack pointer in the thread's control block. */
-; _tx_thread_current_ptr[core] -> tx_thread_stack_ptr = sp;
-;
-; /* Switch to the system stack. */
-; sp = _tx_thread_system_stack_ptr[core];
+; /* This routine runs in IRQ mode on this core's banked IRQ stack, which
+; serves as the system stack on this architecture, so there is no stack
+; switch to perform here. The thread's stack pointer is saved in its
+; control block by _tx_thread_context_restore, and only when the
+; interrupt results in preemption. */
;
MOV r10, #0 ; Clear stack limit
diff --git a/ports_smp/cortex_a9_smp/gnu/CMakeLists.txt b/ports_smp/cortex_a9_smp/gnu/CMakeLists.txt
index 4b13e1a1..dd2c1a41 100644
--- a/ports_smp/cortex_a9_smp/gnu/CMakeLists.txt
+++ b/ports_smp/cortex_a9_smp/gnu/CMakeLists.txt
@@ -26,6 +26,7 @@ target_sources(${PROJECT_NAME}
)
target_include_directories(${PROJECT_NAME}
+ SYSTEM
PUBLIC
${CMAKE_CURRENT_LIST_DIR}/inc
)
diff --git a/ports_smp/cortex_a9_smp/gnu/example_build/build_threadx.sh b/ports_smp/cortex_a9_smp/gnu/example_build/build_threadx.sh
new file mode 100755
index 00000000..8050c775
--- /dev/null
+++ b/ports_smp/cortex_a9_smp/gnu/example_build/build_threadx.sh
@@ -0,0 +1,295 @@
+#!/bin/sh
+##############################################################################
+# 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.
+#
+# SPDX-License-Identifier: MIT
+##############################################################################
+
+set -e
+cd "$(dirname "$0")"
+
+# this script builds the ThreadX library for the Cortex-A9 SMP port using
+# GNU toolchain or llvm/clang toolchain (defaults to GNU).
+: "${TOOLCHAIN:=gnu}"
+
+case "${TOOLCHAIN}" in
+ gnu)
+ CC="arm-none-eabi-gcc"
+ AR="arm-none-eabi-ar"
+ TARGET_FLAGS=""
+ ;;
+ atfe)
+ CC="${ATFE_CLANG:-clang}"
+ case "${CC}" in
+ */*) AR="$(dirname "${CC}")/llvm-ar" ;;
+ *) AR="llvm-ar" ;;
+ esac
+ TARGET_FLAGS="--target=arm-none-eabi"
+ ;;
+ *)
+ echo "Unknown TOOLCHAIN: ${TOOLCHAIN}" >&2
+ exit 1
+ ;;
+esac
+
+rm -f tx.a
+"${CC}" ${TARGET_FLAGS} -c -g -mcpu=cortex-a9 tx_initialize_low_level.S
+"${CC}" ${TARGET_FLAGS} -c -g -mcpu=cortex-a9 ../src/tx_thread_context_restore.S
+"${CC}" ${TARGET_FLAGS} -c -g -mcpu=cortex-a9 ../src/tx_thread_context_save.S
+"${CC}" ${TARGET_FLAGS} -c -g -mcpu=cortex-a9 ../src/tx_thread_interrupt_control.S
+"${CC}" ${TARGET_FLAGS} -c -g -mcpu=cortex-a9 ../src/tx_thread_interrupt_disable.S
+"${CC}" ${TARGET_FLAGS} -c -g -mcpu=cortex-a9 ../src/tx_thread_interrupt_restore.S
+"${CC}" ${TARGET_FLAGS} -c -g -mcpu=cortex-a9 ../src/tx_thread_irq_nesting_end.S
+"${CC}" ${TARGET_FLAGS} -c -g -mcpu=cortex-a9 ../src/tx_thread_irq_nesting_start.S
+"${CC}" ${TARGET_FLAGS} -c -g -mcpu=cortex-a9 ../src/tx_thread_schedule.S
+"${CC}" ${TARGET_FLAGS} -c -g -mcpu=cortex-a9 ../src/tx_thread_smp_core_get.S
+"${CC}" ${TARGET_FLAGS} -c -g -mcpu=cortex-a9 ../src/tx_thread_smp_core_preempt.S
+"${CC}" ${TARGET_FLAGS} -c -g -mcpu=cortex-a9 ../src/tx_thread_smp_current_state_get.S
+"${CC}" ${TARGET_FLAGS} -c -g -mcpu=cortex-a9 ../src/tx_thread_smp_current_thread_get.S
+"${CC}" ${TARGET_FLAGS} -c -g -mcpu=cortex-a9 ../src/tx_thread_smp_initialize_wait.S
+"${CC}" ${TARGET_FLAGS} -c -g -mcpu=cortex-a9 ../src/tx_thread_smp_low_level_initialize.S
+"${CC}" ${TARGET_FLAGS} -c -g -mcpu=cortex-a9 ../src/tx_thread_smp_protect.S
+"${CC}" ${TARGET_FLAGS} -c -g -mcpu=cortex-a9 ../src/tx_thread_smp_time_get.S
+"${CC}" ${TARGET_FLAGS} -c -g -mcpu=cortex-a9 ../src/tx_thread_smp_unprotect.S
+"${CC}" ${TARGET_FLAGS} -c -g -mcpu=cortex-a9 ../src/tx_thread_stack_build.S
+"${CC}" ${TARGET_FLAGS} -c -g -mcpu=cortex-a9 ../src/tx_thread_system_return.S
+"${CC}" ${TARGET_FLAGS} -c -g -mcpu=cortex-a9 ../src/tx_thread_vectored_context_save.S
+"${CC}" ${TARGET_FLAGS} -c -g -mcpu=cortex-a9 ../src/tx_timer_interrupt.S
+"${CC}" ${TARGET_FLAGS} -c -g -mcpu=cortex-a9 -I../../../../common_smp/inc -I../inc ../../../../common_smp/src/tx_block_allocate.c
+"${CC}" ${TARGET_FLAGS} -c -g -mcpu=cortex-a9 -I../../../../common_smp/inc -I../inc ../../../../common_smp/src/tx_block_pool_cleanup.c
+"${CC}" ${TARGET_FLAGS} -c -g -mcpu=cortex-a9 -I../../../../common_smp/inc -I../inc ../../../../common_smp/src/tx_block_pool_create.c
+"${CC}" ${TARGET_FLAGS} -c -g -mcpu=cortex-a9 -I../../../../common_smp/inc -I../inc ../../../../common_smp/src/tx_block_pool_delete.c
+"${CC}" ${TARGET_FLAGS} -c -g -mcpu=cortex-a9 -I../../../../common_smp/inc -I../inc ../../../../common_smp/src/tx_block_pool_info_get.c
+"${CC}" ${TARGET_FLAGS} -c -g -mcpu=cortex-a9 -I../../../../common_smp/inc -I../inc ../../../../common_smp/src/tx_block_pool_initialize.c
+"${CC}" ${TARGET_FLAGS} -c -g -mcpu=cortex-a9 -I../../../../common_smp/inc -I../inc ../../../../common_smp/src/tx_block_pool_performance_info_get.c
+"${CC}" ${TARGET_FLAGS} -c -g -mcpu=cortex-a9 -I../../../../common_smp/inc -I../inc ../../../../common_smp/src/tx_block_pool_performance_system_info_get.c
+"${CC}" ${TARGET_FLAGS} -c -g -mcpu=cortex-a9 -I../../../../common_smp/inc -I../inc ../../../../common_smp/src/tx_block_pool_prioritize.c
+"${CC}" ${TARGET_FLAGS} -c -g -mcpu=cortex-a9 -I../../../../common_smp/inc -I../inc ../../../../common_smp/src/tx_block_release.c
+"${CC}" ${TARGET_FLAGS} -c -g -mcpu=cortex-a9 -I../../../../common_smp/inc -I../inc ../../../../common_smp/src/tx_byte_allocate.c
+"${CC}" ${TARGET_FLAGS} -c -g -mcpu=cortex-a9 -I../../../../common_smp/inc -I../inc ../../../../common_smp/src/tx_byte_pool_cleanup.c
+"${CC}" ${TARGET_FLAGS} -c -g -mcpu=cortex-a9 -I../../../../common_smp/inc -I../inc ../../../../common_smp/src/tx_byte_pool_create.c
+"${CC}" ${TARGET_FLAGS} -c -g -mcpu=cortex-a9 -I../../../../common_smp/inc -I../inc ../../../../common_smp/src/tx_byte_pool_delete.c
+"${CC}" ${TARGET_FLAGS} -c -g -mcpu=cortex-a9 -I../../../../common_smp/inc -I../inc ../../../../common_smp/src/tx_byte_pool_info_get.c
+"${CC}" ${TARGET_FLAGS} -c -g -mcpu=cortex-a9 -I../../../../common_smp/inc -I../inc ../../../../common_smp/src/tx_byte_pool_initialize.c
+"${CC}" ${TARGET_FLAGS} -c -g -mcpu=cortex-a9 -I../../../../common_smp/inc -I../inc ../../../../common_smp/src/tx_byte_pool_performance_info_get.c
+"${CC}" ${TARGET_FLAGS} -c -g -mcpu=cortex-a9 -I../../../../common_smp/inc -I../inc ../../../../common_smp/src/tx_byte_pool_performance_system_info_get.c
+"${CC}" ${TARGET_FLAGS} -c -g -mcpu=cortex-a9 -I../../../../common_smp/inc -I../inc ../../../../common_smp/src/tx_byte_pool_prioritize.c
+"${CC}" ${TARGET_FLAGS} -c -g -mcpu=cortex-a9 -I../../../../common_smp/inc -I../inc ../../../../common_smp/src/tx_byte_pool_search.c
+"${CC}" ${TARGET_FLAGS} -c -g -mcpu=cortex-a9 -I../../../../common_smp/inc -I../inc ../../../../common_smp/src/tx_byte_release.c
+"${CC}" ${TARGET_FLAGS} -c -g -mcpu=cortex-a9 -I../../../../common_smp/inc -I../inc ../../../../common_smp/src/tx_event_flags_cleanup.c
+"${CC}" ${TARGET_FLAGS} -c -g -mcpu=cortex-a9 -I../../../../common_smp/inc -I../inc ../../../../common_smp/src/tx_event_flags_create.c
+"${CC}" ${TARGET_FLAGS} -c -g -mcpu=cortex-a9 -I../../../../common_smp/inc -I../inc ../../../../common_smp/src/tx_event_flags_delete.c
+"${CC}" ${TARGET_FLAGS} -c -g -mcpu=cortex-a9 -I../../../../common_smp/inc -I../inc ../../../../common_smp/src/tx_event_flags_get.c
+"${CC}" ${TARGET_FLAGS} -c -g -mcpu=cortex-a9 -I../../../../common_smp/inc -I../inc ../../../../common_smp/src/tx_event_flags_info_get.c
+"${CC}" ${TARGET_FLAGS} -c -g -mcpu=cortex-a9 -I../../../../common_smp/inc -I../inc ../../../../common_smp/src/tx_event_flags_initialize.c
+"${CC}" ${TARGET_FLAGS} -c -g -mcpu=cortex-a9 -I../../../../common_smp/inc -I../inc ../../../../common_smp/src/tx_event_flags_performance_info_get.c
+"${CC}" ${TARGET_FLAGS} -c -g -mcpu=cortex-a9 -I../../../../common_smp/inc -I../inc ../../../../common_smp/src/tx_event_flags_performance_system_info_get.c
+"${CC}" ${TARGET_FLAGS} -c -g -mcpu=cortex-a9 -I../../../../common_smp/inc -I../inc ../../../../common_smp/src/tx_event_flags_set.c
+"${CC}" ${TARGET_FLAGS} -c -g -mcpu=cortex-a9 -I../../../../common_smp/inc -I../inc ../../../../common_smp/src/tx_event_flags_set_notify.c
+"${CC}" ${TARGET_FLAGS} -c -g -mcpu=cortex-a9 -I../../../../common_smp/inc -I../inc ../../../../common_smp/src/tx_initialize_high_level.c
+"${CC}" ${TARGET_FLAGS} -c -g -mcpu=cortex-a9 -I../../../../common_smp/inc -I../inc ../../../../common_smp/src/tx_initialize_kernel_enter.c
+"${CC}" ${TARGET_FLAGS} -c -g -mcpu=cortex-a9 -I../../../../common_smp/inc -I../inc ../../../../common_smp/src/tx_initialize_kernel_setup.c
+"${CC}" ${TARGET_FLAGS} -c -g -mcpu=cortex-a9 -I../../../../common_smp/inc -I../inc ../../../../common_smp/src/tx_mutex_cleanup.c
+"${CC}" ${TARGET_FLAGS} -c -g -mcpu=cortex-a9 -I../../../../common_smp/inc -I../inc ../../../../common_smp/src/tx_mutex_create.c
+"${CC}" ${TARGET_FLAGS} -c -g -mcpu=cortex-a9 -I../../../../common_smp/inc -I../inc ../../../../common_smp/src/tx_mutex_delete.c
+"${CC}" ${TARGET_FLAGS} -c -g -mcpu=cortex-a9 -I../../../../common_smp/inc -I../inc ../../../../common_smp/src/tx_mutex_get.c
+"${CC}" ${TARGET_FLAGS} -c -g -mcpu=cortex-a9 -I../../../../common_smp/inc -I../inc ../../../../common_smp/src/tx_mutex_info_get.c
+"${CC}" ${TARGET_FLAGS} -c -g -mcpu=cortex-a9 -I../../../../common_smp/inc -I../inc ../../../../common_smp/src/tx_mutex_initialize.c
+"${CC}" ${TARGET_FLAGS} -c -g -mcpu=cortex-a9 -I../../../../common_smp/inc -I../inc ../../../../common_smp/src/tx_mutex_performance_info_get.c
+"${CC}" ${TARGET_FLAGS} -c -g -mcpu=cortex-a9 -I../../../../common_smp/inc -I../inc ../../../../common_smp/src/tx_mutex_performance_system_info_get.c
+"${CC}" ${TARGET_FLAGS} -c -g -mcpu=cortex-a9 -I../../../../common_smp/inc -I../inc ../../../../common_smp/src/tx_mutex_prioritize.c
+"${CC}" ${TARGET_FLAGS} -c -g -mcpu=cortex-a9 -I../../../../common_smp/inc -I../inc ../../../../common_smp/src/tx_mutex_priority_change.c
+"${CC}" ${TARGET_FLAGS} -c -g -mcpu=cortex-a9 -I../../../../common_smp/inc -I../inc ../../../../common_smp/src/tx_mutex_put.c
+"${CC}" ${TARGET_FLAGS} -c -g -mcpu=cortex-a9 -I../../../../common_smp/inc -I../inc ../../../../common_smp/src/tx_queue_cleanup.c
+"${CC}" ${TARGET_FLAGS} -c -g -mcpu=cortex-a9 -I../../../../common_smp/inc -I../inc ../../../../common_smp/src/tx_queue_create.c
+"${CC}" ${TARGET_FLAGS} -c -g -mcpu=cortex-a9 -I../../../../common_smp/inc -I../inc ../../../../common_smp/src/tx_queue_delete.c
+"${CC}" ${TARGET_FLAGS} -c -g -mcpu=cortex-a9 -I../../../../common_smp/inc -I../inc ../../../../common_smp/src/tx_queue_flush.c
+"${CC}" ${TARGET_FLAGS} -c -g -mcpu=cortex-a9 -I../../../../common_smp/inc -I../inc ../../../../common_smp/src/tx_queue_front_send.c
+"${CC}" ${TARGET_FLAGS} -c -g -mcpu=cortex-a9 -I../../../../common_smp/inc -I../inc ../../../../common_smp/src/tx_queue_info_get.c
+"${CC}" ${TARGET_FLAGS} -c -g -mcpu=cortex-a9 -I../../../../common_smp/inc -I../inc ../../../../common_smp/src/tx_queue_initialize.c
+"${CC}" ${TARGET_FLAGS} -c -g -mcpu=cortex-a9 -I../../../../common_smp/inc -I../inc ../../../../common_smp/src/tx_queue_performance_info_get.c
+"${CC}" ${TARGET_FLAGS} -c -g -mcpu=cortex-a9 -I../../../../common_smp/inc -I../inc ../../../../common_smp/src/tx_queue_performance_system_info_get.c
+"${CC}" ${TARGET_FLAGS} -c -g -mcpu=cortex-a9 -I../../../../common_smp/inc -I../inc ../../../../common_smp/src/tx_queue_prioritize.c
+"${CC}" ${TARGET_FLAGS} -c -g -mcpu=cortex-a9 -I../../../../common_smp/inc -I../inc ../../../../common_smp/src/tx_queue_receive.c
+"${CC}" ${TARGET_FLAGS} -c -g -mcpu=cortex-a9 -I../../../../common_smp/inc -I../inc ../../../../common_smp/src/tx_queue_send.c
+"${CC}" ${TARGET_FLAGS} -c -g -mcpu=cortex-a9 -I../../../../common_smp/inc -I../inc ../../../../common_smp/src/tx_queue_send_notify.c
+"${CC}" ${TARGET_FLAGS} -c -g -mcpu=cortex-a9 -I../../../../common_smp/inc -I../inc ../../../../common_smp/src/tx_semaphore_ceiling_put.c
+"${CC}" ${TARGET_FLAGS} -c -g -mcpu=cortex-a9 -I../../../../common_smp/inc -I../inc ../../../../common_smp/src/tx_semaphore_cleanup.c
+"${CC}" ${TARGET_FLAGS} -c -g -mcpu=cortex-a9 -I../../../../common_smp/inc -I../inc ../../../../common_smp/src/tx_semaphore_create.c
+"${CC}" ${TARGET_FLAGS} -c -g -mcpu=cortex-a9 -I../../../../common_smp/inc -I../inc ../../../../common_smp/src/tx_semaphore_delete.c
+"${CC}" ${TARGET_FLAGS} -c -g -mcpu=cortex-a9 -I../../../../common_smp/inc -I../inc ../../../../common_smp/src/tx_semaphore_get.c
+"${CC}" ${TARGET_FLAGS} -c -g -mcpu=cortex-a9 -I../../../../common_smp/inc -I../inc ../../../../common_smp/src/tx_semaphore_info_get.c
+"${CC}" ${TARGET_FLAGS} -c -g -mcpu=cortex-a9 -I../../../../common_smp/inc -I../inc ../../../../common_smp/src/tx_semaphore_initialize.c
+"${CC}" ${TARGET_FLAGS} -c -g -mcpu=cortex-a9 -I../../../../common_smp/inc -I../inc ../../../../common_smp/src/tx_semaphore_performance_info_get.c
+"${CC}" ${TARGET_FLAGS} -c -g -mcpu=cortex-a9 -I../../../../common_smp/inc -I../inc ../../../../common_smp/src/tx_semaphore_performance_system_info_get.c
+"${CC}" ${TARGET_FLAGS} -c -g -mcpu=cortex-a9 -I../../../../common_smp/inc -I../inc ../../../../common_smp/src/tx_semaphore_prioritize.c
+"${CC}" ${TARGET_FLAGS} -c -g -mcpu=cortex-a9 -I../../../../common_smp/inc -I../inc ../../../../common_smp/src/tx_semaphore_put.c
+"${CC}" ${TARGET_FLAGS} -c -g -mcpu=cortex-a9 -I../../../../common_smp/inc -I../inc ../../../../common_smp/src/tx_semaphore_put_notify.c
+"${CC}" ${TARGET_FLAGS} -c -g -mcpu=cortex-a9 -I../../../../common_smp/inc -I../inc ../../../../common_smp/src/tx_thread_create.c
+"${CC}" ${TARGET_FLAGS} -c -g -mcpu=cortex-a9 -I../../../../common_smp/inc -I../inc ../../../../common_smp/src/tx_thread_delete.c
+"${CC}" ${TARGET_FLAGS} -c -g -mcpu=cortex-a9 -I../../../../common_smp/inc -I../inc ../../../../common_smp/src/tx_thread_entry_exit_notify.c
+"${CC}" ${TARGET_FLAGS} -c -g -mcpu=cortex-a9 -I../../../../common_smp/inc -I../inc ../../../../common_smp/src/tx_thread_identify.c
+"${CC}" ${TARGET_FLAGS} -c -g -mcpu=cortex-a9 -I../../../../common_smp/inc -I../inc ../../../../common_smp/src/tx_thread_info_get.c
+"${CC}" ${TARGET_FLAGS} -c -g -mcpu=cortex-a9 -I../../../../common_smp/inc -I../inc ../../../../common_smp/src/tx_thread_initialize.c
+"${CC}" ${TARGET_FLAGS} -c -g -mcpu=cortex-a9 -I../../../../common_smp/inc -I../inc ../../../../common_smp/src/tx_thread_performance_info_get.c
+"${CC}" ${TARGET_FLAGS} -c -g -mcpu=cortex-a9 -I../../../../common_smp/inc -I../inc ../../../../common_smp/src/tx_thread_performance_system_info_get.c
+"${CC}" ${TARGET_FLAGS} -c -g -mcpu=cortex-a9 -I../../../../common_smp/inc -I../inc ../../../../common_smp/src/tx_thread_preemption_change.c
+"${CC}" ${TARGET_FLAGS} -c -g -mcpu=cortex-a9 -I../../../../common_smp/inc -I../inc ../../../../common_smp/src/tx_thread_priority_change.c
+"${CC}" ${TARGET_FLAGS} -c -g -mcpu=cortex-a9 -I../../../../common_smp/inc -I../inc ../../../../common_smp/src/tx_thread_relinquish.c
+"${CC}" ${TARGET_FLAGS} -c -g -mcpu=cortex-a9 -I../../../../common_smp/inc -I../inc ../../../../common_smp/src/tx_thread_reset.c
+"${CC}" ${TARGET_FLAGS} -c -g -mcpu=cortex-a9 -I../../../../common_smp/inc -I../inc ../../../../common_smp/src/tx_thread_resume.c
+"${CC}" ${TARGET_FLAGS} -c -g -mcpu=cortex-a9 -I../../../../common_smp/inc -I../inc ../../../../common_smp/src/tx_thread_shell_entry.c
+"${CC}" ${TARGET_FLAGS} -c -g -mcpu=cortex-a9 -I../../../../common_smp/inc -I../inc ../../../../common_smp/src/tx_thread_sleep.c
+"${CC}" ${TARGET_FLAGS} -c -g -mcpu=cortex-a9 -I../../../../common_smp/inc -I../inc ../../../../common_smp/src/tx_thread_stack_analyze.c
+"${CC}" ${TARGET_FLAGS} -c -g -mcpu=cortex-a9 -I../../../../common_smp/inc -I../inc ../../../../common_smp/src/tx_thread_stack_error_handler.c
+"${CC}" ${TARGET_FLAGS} -c -g -mcpu=cortex-a9 -I../../../../common_smp/inc -I../inc ../../../../common_smp/src/tx_thread_stack_error_notify.c
+"${CC}" ${TARGET_FLAGS} -c -g -mcpu=cortex-a9 -I../../../../common_smp/inc -I../inc ../../../../common_smp/src/tx_thread_suspend.c
+"${CC}" ${TARGET_FLAGS} -c -g -mcpu=cortex-a9 -I../../../../common_smp/inc -I../inc ../../../../common_smp/src/tx_thread_system_preempt_check.c
+"${CC}" ${TARGET_FLAGS} -c -g -mcpu=cortex-a9 -I../../../../common_smp/inc -I../inc ../../../../common_smp/src/tx_thread_system_resume.c
+"${CC}" ${TARGET_FLAGS} -c -g -mcpu=cortex-a9 -I../../../../common_smp/inc -I../inc ../../../../common_smp/src/tx_thread_system_suspend.c
+"${CC}" ${TARGET_FLAGS} -c -g -mcpu=cortex-a9 -I../../../../common_smp/inc -I../inc ../../../../common_smp/src/tx_thread_terminate.c
+"${CC}" ${TARGET_FLAGS} -c -g -mcpu=cortex-a9 -I../../../../common_smp/inc -I../inc ../../../../common_smp/src/tx_thread_time_slice.c
+"${CC}" ${TARGET_FLAGS} -c -g -mcpu=cortex-a9 -I../../../../common_smp/inc -I../inc ../../../../common_smp/src/tx_thread_time_slice_change.c
+"${CC}" ${TARGET_FLAGS} -c -g -mcpu=cortex-a9 -I../../../../common_smp/inc -I../inc ../../../../common_smp/src/tx_thread_timeout.c
+"${CC}" ${TARGET_FLAGS} -c -g -mcpu=cortex-a9 -I../../../../common_smp/inc -I../inc ../../../../common_smp/src/tx_thread_wait_abort.c
+"${CC}" ${TARGET_FLAGS} -c -g -mcpu=cortex-a9 -I../../../../common_smp/inc -I../inc ../../../../common_smp/src/tx_time_get.c
+"${CC}" ${TARGET_FLAGS} -c -g -mcpu=cortex-a9 -I../../../../common_smp/inc -I../inc ../../../../common_smp/src/tx_time_set.c
+"${CC}" ${TARGET_FLAGS} -c -g -mcpu=cortex-a9 -I../../../../common_smp/inc -I../inc ../../../../common_smp/src/tx_timer_activate.c
+"${CC}" ${TARGET_FLAGS} -c -g -mcpu=cortex-a9 -I../../../../common_smp/inc -I../inc ../../../../common_smp/src/tx_timer_change.c
+"${CC}" ${TARGET_FLAGS} -c -g -mcpu=cortex-a9 -I../../../../common_smp/inc -I../inc ../../../../common_smp/src/tx_timer_create.c
+"${CC}" ${TARGET_FLAGS} -c -g -mcpu=cortex-a9 -I../../../../common_smp/inc -I../inc ../../../../common_smp/src/tx_timer_deactivate.c
+"${CC}" ${TARGET_FLAGS} -c -g -mcpu=cortex-a9 -I../../../../common_smp/inc -I../inc ../../../../common_smp/src/tx_timer_delete.c
+"${CC}" ${TARGET_FLAGS} -c -g -mcpu=cortex-a9 -I../../../../common_smp/inc -I../inc ../../../../common_smp/src/tx_timer_expiration_process.c
+"${CC}" ${TARGET_FLAGS} -c -g -mcpu=cortex-a9 -I../../../../common_smp/inc -I../inc ../../../../common_smp/src/tx_timer_info_get.c
+"${CC}" ${TARGET_FLAGS} -c -g -mcpu=cortex-a9 -I../../../../common_smp/inc -I../inc ../../../../common_smp/src/tx_timer_initialize.c
+"${CC}" ${TARGET_FLAGS} -c -g -mcpu=cortex-a9 -I../../../../common_smp/inc -I../inc ../../../../common_smp/src/tx_timer_performance_info_get.c
+"${CC}" ${TARGET_FLAGS} -c -g -mcpu=cortex-a9 -I../../../../common_smp/inc -I../inc ../../../../common_smp/src/tx_timer_performance_system_info_get.c
+"${CC}" ${TARGET_FLAGS} -c -g -mcpu=cortex-a9 -I../../../../common_smp/inc -I../inc ../../../../common_smp/src/tx_timer_system_activate.c
+"${CC}" ${TARGET_FLAGS} -c -g -mcpu=cortex-a9 -I../../../../common_smp/inc -I../inc ../../../../common_smp/src/tx_timer_system_deactivate.c
+"${CC}" ${TARGET_FLAGS} -c -g -mcpu=cortex-a9 -I../../../../common_smp/inc -I../inc ../../../../common_smp/src/tx_timer_thread_entry.c
+"${CC}" ${TARGET_FLAGS} -c -g -mcpu=cortex-a9 -I../../../../common_smp/inc -I../inc ../../../../common_smp/src/tx_trace_enable.c
+"${CC}" ${TARGET_FLAGS} -c -g -mcpu=cortex-a9 -I../../../../common_smp/inc -I../inc ../../../../common_smp/src/tx_trace_disable.c
+"${CC}" ${TARGET_FLAGS} -c -g -mcpu=cortex-a9 -I../../../../common_smp/inc -I../inc ../../../../common_smp/src/tx_trace_initialize.c
+"${CC}" ${TARGET_FLAGS} -c -g -mcpu=cortex-a9 -I../../../../common_smp/inc -I../inc ../../../../common_smp/src/tx_trace_interrupt_control.c
+"${CC}" ${TARGET_FLAGS} -c -g -mcpu=cortex-a9 -I../../../../common_smp/inc -I../inc ../../../../common_smp/src/tx_trace_isr_enter_insert.c
+"${CC}" ${TARGET_FLAGS} -c -g -mcpu=cortex-a9 -I../../../../common_smp/inc -I../inc ../../../../common_smp/src/tx_trace_isr_exit_insert.c
+"${CC}" ${TARGET_FLAGS} -c -g -mcpu=cortex-a9 -I../../../../common_smp/inc -I../inc ../../../../common_smp/src/tx_trace_object_register.c
+"${CC}" ${TARGET_FLAGS} -c -g -mcpu=cortex-a9 -I../../../../common_smp/inc -I../inc ../../../../common_smp/src/tx_trace_object_unregister.c
+"${CC}" ${TARGET_FLAGS} -c -g -mcpu=cortex-a9 -I../../../../common_smp/inc -I../inc ../../../../common_smp/src/tx_trace_user_event_insert.c
+"${CC}" ${TARGET_FLAGS} -c -g -mcpu=cortex-a9 -I../../../../common_smp/inc -I../inc ../../../../common_smp/src/tx_trace_buffer_full_notify.c
+"${CC}" ${TARGET_FLAGS} -c -g -mcpu=cortex-a9 -I../../../../common_smp/inc -I../inc ../../../../common_smp/src/tx_trace_event_filter.c
+"${CC}" ${TARGET_FLAGS} -c -g -mcpu=cortex-a9 -I../../../../common_smp/inc -I../inc ../../../../common_smp/src/tx_trace_event_unfilter.c
+"${CC}" ${TARGET_FLAGS} -c -g -mcpu=cortex-a9 -I../../../../common_smp/inc -I../inc ../../../../common_smp/src/txe_block_allocate.c
+"${CC}" ${TARGET_FLAGS} -c -g -mcpu=cortex-a9 -I../../../../common_smp/inc -I../inc ../../../../common_smp/src/txe_block_pool_create.c
+"${CC}" ${TARGET_FLAGS} -c -g -mcpu=cortex-a9 -I../../../../common_smp/inc -I../inc ../../../../common_smp/src/txe_block_pool_delete.c
+"${CC}" ${TARGET_FLAGS} -c -g -mcpu=cortex-a9 -I../../../../common_smp/inc -I../inc ../../../../common_smp/src/txe_block_pool_info_get.c
+"${CC}" ${TARGET_FLAGS} -c -g -mcpu=cortex-a9 -I../../../../common_smp/inc -I../inc ../../../../common_smp/src/txe_block_pool_prioritize.c
+"${CC}" ${TARGET_FLAGS} -c -g -mcpu=cortex-a9 -I../../../../common_smp/inc -I../inc ../../../../common_smp/src/txe_block_release.c
+"${CC}" ${TARGET_FLAGS} -c -g -mcpu=cortex-a9 -I../../../../common_smp/inc -I../inc ../../../../common_smp/src/txe_byte_allocate.c
+"${CC}" ${TARGET_FLAGS} -c -g -mcpu=cortex-a9 -I../../../../common_smp/inc -I../inc ../../../../common_smp/src/txe_byte_pool_create.c
+"${CC}" ${TARGET_FLAGS} -c -g -mcpu=cortex-a9 -I../../../../common_smp/inc -I../inc ../../../../common_smp/src/txe_byte_pool_delete.c
+"${CC}" ${TARGET_FLAGS} -c -g -mcpu=cortex-a9 -I../../../../common_smp/inc -I../inc ../../../../common_smp/src/txe_byte_pool_info_get.c
+"${CC}" ${TARGET_FLAGS} -c -g -mcpu=cortex-a9 -I../../../../common_smp/inc -I../inc ../../../../common_smp/src/txe_byte_pool_prioritize.c
+"${CC}" ${TARGET_FLAGS} -c -g -mcpu=cortex-a9 -I../../../../common_smp/inc -I../inc ../../../../common_smp/src/txe_byte_release.c
+"${CC}" ${TARGET_FLAGS} -c -g -mcpu=cortex-a9 -I../../../../common_smp/inc -I../inc ../../../../common_smp/src/txe_event_flags_create.c
+"${CC}" ${TARGET_FLAGS} -c -g -mcpu=cortex-a9 -I../../../../common_smp/inc -I../inc ../../../../common_smp/src/txe_event_flags_delete.c
+"${CC}" ${TARGET_FLAGS} -c -g -mcpu=cortex-a9 -I../../../../common_smp/inc -I../inc ../../../../common_smp/src/txe_event_flags_get.c
+"${CC}" ${TARGET_FLAGS} -c -g -mcpu=cortex-a9 -I../../../../common_smp/inc -I../inc ../../../../common_smp/src/txe_event_flags_info_get.c
+"${CC}" ${TARGET_FLAGS} -c -g -mcpu=cortex-a9 -I../../../../common_smp/inc -I../inc ../../../../common_smp/src/txe_event_flags_set.c
+"${CC}" ${TARGET_FLAGS} -c -g -mcpu=cortex-a9 -I../../../../common_smp/inc -I../inc ../../../../common_smp/src/txe_event_flags_set_notify.c
+"${CC}" ${TARGET_FLAGS} -c -g -mcpu=cortex-a9 -I../../../../common_smp/inc -I../inc ../../../../common_smp/src/txe_mutex_create.c
+"${CC}" ${TARGET_FLAGS} -c -g -mcpu=cortex-a9 -I../../../../common_smp/inc -I../inc ../../../../common_smp/src/txe_mutex_delete.c
+"${CC}" ${TARGET_FLAGS} -c -g -mcpu=cortex-a9 -I../../../../common_smp/inc -I../inc ../../../../common_smp/src/txe_mutex_get.c
+"${CC}" ${TARGET_FLAGS} -c -g -mcpu=cortex-a9 -I../../../../common_smp/inc -I../inc ../../../../common_smp/src/txe_mutex_info_get.c
+"${CC}" ${TARGET_FLAGS} -c -g -mcpu=cortex-a9 -I../../../../common_smp/inc -I../inc ../../../../common_smp/src/txe_mutex_prioritize.c
+"${CC}" ${TARGET_FLAGS} -c -g -mcpu=cortex-a9 -I../../../../common_smp/inc -I../inc ../../../../common_smp/src/txe_mutex_put.c
+"${CC}" ${TARGET_FLAGS} -c -g -mcpu=cortex-a9 -I../../../../common_smp/inc -I../inc ../../../../common_smp/src/txe_queue_create.c
+"${CC}" ${TARGET_FLAGS} -c -g -mcpu=cortex-a9 -I../../../../common_smp/inc -I../inc ../../../../common_smp/src/txe_queue_delete.c
+"${CC}" ${TARGET_FLAGS} -c -g -mcpu=cortex-a9 -I../../../../common_smp/inc -I../inc ../../../../common_smp/src/txe_queue_flush.c
+"${CC}" ${TARGET_FLAGS} -c -g -mcpu=cortex-a9 -I../../../../common_smp/inc -I../inc ../../../../common_smp/src/txe_queue_front_send.c
+"${CC}" ${TARGET_FLAGS} -c -g -mcpu=cortex-a9 -I../../../../common_smp/inc -I../inc ../../../../common_smp/src/txe_queue_info_get.c
+"${CC}" ${TARGET_FLAGS} -c -g -mcpu=cortex-a9 -I../../../../common_smp/inc -I../inc ../../../../common_smp/src/txe_queue_prioritize.c
+"${CC}" ${TARGET_FLAGS} -c -g -mcpu=cortex-a9 -I../../../../common_smp/inc -I../inc ../../../../common_smp/src/txe_queue_receive.c
+"${CC}" ${TARGET_FLAGS} -c -g -mcpu=cortex-a9 -I../../../../common_smp/inc -I../inc ../../../../common_smp/src/txe_queue_send.c
+"${CC}" ${TARGET_FLAGS} -c -g -mcpu=cortex-a9 -I../../../../common_smp/inc -I../inc ../../../../common_smp/src/txe_queue_send_notify.c
+"${CC}" ${TARGET_FLAGS} -c -g -mcpu=cortex-a9 -I../../../../common_smp/inc -I../inc ../../../../common_smp/src/txe_semaphore_ceiling_put.c
+"${CC}" ${TARGET_FLAGS} -c -g -mcpu=cortex-a9 -I../../../../common_smp/inc -I../inc ../../../../common_smp/src/txe_semaphore_create.c
+"${CC}" ${TARGET_FLAGS} -c -g -mcpu=cortex-a9 -I../../../../common_smp/inc -I../inc ../../../../common_smp/src/txe_semaphore_delete.c
+"${CC}" ${TARGET_FLAGS} -c -g -mcpu=cortex-a9 -I../../../../common_smp/inc -I../inc ../../../../common_smp/src/txe_semaphore_get.c
+"${CC}" ${TARGET_FLAGS} -c -g -mcpu=cortex-a9 -I../../../../common_smp/inc -I../inc ../../../../common_smp/src/txe_semaphore_info_get.c
+"${CC}" ${TARGET_FLAGS} -c -g -mcpu=cortex-a9 -I../../../../common_smp/inc -I../inc ../../../../common_smp/src/txe_semaphore_prioritize.c
+"${CC}" ${TARGET_FLAGS} -c -g -mcpu=cortex-a9 -I../../../../common_smp/inc -I../inc ../../../../common_smp/src/txe_semaphore_put.c
+"${CC}" ${TARGET_FLAGS} -c -g -mcpu=cortex-a9 -I../../../../common_smp/inc -I../inc ../../../../common_smp/src/txe_semaphore_put_notify.c
+"${CC}" ${TARGET_FLAGS} -c -g -mcpu=cortex-a9 -I../../../../common_smp/inc -I../inc ../../../../common_smp/src/txe_thread_create.c
+"${CC}" ${TARGET_FLAGS} -c -g -mcpu=cortex-a9 -I../../../../common_smp/inc -I../inc ../../../../common_smp/src/txe_thread_delete.c
+"${CC}" ${TARGET_FLAGS} -c -g -mcpu=cortex-a9 -I../../../../common_smp/inc -I../inc ../../../../common_smp/src/txe_thread_entry_exit_notify.c
+"${CC}" ${TARGET_FLAGS} -c -g -mcpu=cortex-a9 -I../../../../common_smp/inc -I../inc ../../../../common_smp/src/txe_thread_info_get.c
+"${CC}" ${TARGET_FLAGS} -c -g -mcpu=cortex-a9 -I../../../../common_smp/inc -I../inc ../../../../common_smp/src/txe_thread_preemption_change.c
+"${CC}" ${TARGET_FLAGS} -c -g -mcpu=cortex-a9 -I../../../../common_smp/inc -I../inc ../../../../common_smp/src/txe_thread_priority_change.c
+"${CC}" ${TARGET_FLAGS} -c -g -mcpu=cortex-a9 -I../../../../common_smp/inc -I../inc ../../../../common_smp/src/txe_thread_relinquish.c
+"${CC}" ${TARGET_FLAGS} -c -g -mcpu=cortex-a9 -I../../../../common_smp/inc -I../inc ../../../../common_smp/src/txe_thread_reset.c
+"${CC}" ${TARGET_FLAGS} -c -g -mcpu=cortex-a9 -I../../../../common_smp/inc -I../inc ../../../../common_smp/src/txe_thread_resume.c
+"${CC}" ${TARGET_FLAGS} -c -g -mcpu=cortex-a9 -I../../../../common_smp/inc -I../inc ../../../../common_smp/src/txe_thread_suspend.c
+"${CC}" ${TARGET_FLAGS} -c -g -mcpu=cortex-a9 -I../../../../common_smp/inc -I../inc ../../../../common_smp/src/txe_thread_terminate.c
+"${CC}" ${TARGET_FLAGS} -c -g -mcpu=cortex-a9 -I../../../../common_smp/inc -I../inc ../../../../common_smp/src/txe_thread_time_slice_change.c
+"${CC}" ${TARGET_FLAGS} -c -g -mcpu=cortex-a9 -I../../../../common_smp/inc -I../inc ../../../../common_smp/src/txe_thread_wait_abort.c
+"${CC}" ${TARGET_FLAGS} -c -g -mcpu=cortex-a9 -I../../../../common_smp/inc -I../inc ../../../../common_smp/src/txe_timer_activate.c
+"${CC}" ${TARGET_FLAGS} -c -g -mcpu=cortex-a9 -I../../../../common_smp/inc -I../inc ../../../../common_smp/src/txe_timer_change.c
+"${CC}" ${TARGET_FLAGS} -c -g -mcpu=cortex-a9 -I../../../../common_smp/inc -I../inc ../../../../common_smp/src/txe_timer_create.c
+"${CC}" ${TARGET_FLAGS} -c -g -mcpu=cortex-a9 -I../../../../common_smp/inc -I../inc ../../../../common_smp/src/txe_timer_deactivate.c
+"${CC}" ${TARGET_FLAGS} -c -g -mcpu=cortex-a9 -I../../../../common_smp/inc -I../inc ../../../../common_smp/src/txe_timer_delete.c
+"${CC}" ${TARGET_FLAGS} -c -g -mcpu=cortex-a9 -I../../../../common_smp/inc -I../inc ../../../../common_smp/src/txe_timer_info_get.c
+"${CC}" ${TARGET_FLAGS} -c -g -mcpu=cortex-a9 -I../../../../common_smp/inc -I../inc ../../../../common_smp/src/tx_thread_smp_current_state_set.c
+"${CC}" ${TARGET_FLAGS} -c -g -mcpu=cortex-a9 -I../../../../common_smp/inc -I../inc ../../../../common_smp/src/tx_thread_smp_debug_entry_insert.c
+"${CC}" ${TARGET_FLAGS} -c -g -mcpu=cortex-a9 -I../../../../common_smp/inc -I../inc ../../../../common_smp/src/tx_thread_smp_high_level_initialize.c
+"${CC}" ${TARGET_FLAGS} -c -g -mcpu=cortex-a9 -I../../../../common_smp/inc -I../inc ../../../../common_smp/src/tx_thread_smp_rebalance_execute_list.c
+"${CC}" ${TARGET_FLAGS} -c -g -mcpu=cortex-a9 -I../../../../common_smp/inc -I../inc ../../../../common_smp/src/tx_thread_smp_core_exclude.c
+"${CC}" ${TARGET_FLAGS} -c -g -mcpu=cortex-a9 -I../../../../common_smp/inc -I../inc ../../../../common_smp/src/tx_thread_smp_core_exclude_get.c
+"${CC}" ${TARGET_FLAGS} -c -g -mcpu=cortex-a9 -I../../../../common_smp/inc -I../inc ../../../../common_smp/src/tx_timer_smp_core_exclude.c
+"${CC}" ${TARGET_FLAGS} -c -g -mcpu=cortex-a9 -I../../../../common_smp/inc -I../inc ../../../../common_smp/src/tx_timer_smp_core_exclude_get.c
+"${CC}" ${TARGET_FLAGS} -c -g -mcpu=cortex-a9 -I../../../../common_smp/inc -I../inc ../../../../common_smp/src/tx_thread_smp_utilities.c
+"${AR}" -r tx.a tx_thread_stack_build.o tx_thread_schedule.o tx_thread_system_return.o tx_thread_context_save.o tx_thread_context_restore.o tx_timer_interrupt.o tx_thread_interrupt_control.o
+"${AR}" -r tx.a tx_initialize_low_level.o tx_thread_interrupt_disable.o
+"${AR}" -r tx.a tx_thread_interrupt_restore.o tx_thread_irq_nesting_end.o tx_thread_irq_nesting_start.o
+"${AR}" -r tx.a tx_block_allocate.o tx_block_pool_cleanup.o tx_block_pool_create.o tx_block_pool_delete.o tx_block_pool_info_get.o
+"${AR}" -r tx.a tx_block_pool_initialize.o tx_block_pool_performance_info_get.o tx_block_pool_performance_system_info_get.o tx_block_pool_prioritize.o
+"${AR}" -r tx.a tx_block_release.o tx_byte_allocate.o tx_byte_pool_cleanup.o tx_byte_pool_create.o tx_byte_pool_delete.o tx_byte_pool_info_get.o
+"${AR}" -r tx.a tx_byte_pool_initialize.o tx_byte_pool_performance_info_get.o tx_byte_pool_performance_system_info_get.o tx_byte_pool_prioritize.o
+"${AR}" -r tx.a tx_byte_pool_search.o tx_byte_release.o tx_event_flags_cleanup.o tx_event_flags_create.o tx_event_flags_delete.o tx_event_flags_get.o
+"${AR}" -r tx.a tx_event_flags_info_get.o tx_event_flags_initialize.o tx_event_flags_performance_info_get.o tx_event_flags_performance_system_info_get.o
+"${AR}" -r tx.a tx_event_flags_set.o tx_event_flags_set_notify.o tx_initialize_high_level.o tx_initialize_kernel_enter.o tx_initialize_kernel_setup.o
+"${AR}" -r tx.a tx_mutex_cleanup.o tx_mutex_create.o tx_mutex_delete.o tx_mutex_get.o tx_mutex_info_get.o tx_mutex_initialize.o tx_mutex_performance_info_get.o
+"${AR}" -r tx.a tx_mutex_performance_system_info_get.o tx_mutex_prioritize.o tx_mutex_priority_change.o tx_mutex_put.o tx_queue_cleanup.o tx_queue_create.o
+"${AR}" -r tx.a tx_queue_delete.o tx_queue_flush.o tx_queue_front_send.o tx_queue_info_get.o tx_queue_initialize.o tx_queue_performance_info_get.o
+"${AR}" -r tx.a tx_queue_performance_system_info_get.o tx_queue_prioritize.o tx_queue_receive.o tx_queue_send.o tx_queue_send_notify.o tx_semaphore_ceiling_put.o
+"${AR}" -r tx.a tx_semaphore_cleanup.o tx_semaphore_create.o tx_semaphore_delete.o tx_semaphore_get.o tx_semaphore_info_get.o tx_semaphore_initialize.o
+"${AR}" -r tx.a tx_semaphore_performance_info_get.o tx_semaphore_performance_system_info_get.o tx_semaphore_prioritize.o tx_semaphore_put.o tx_semaphore_put_notify.o
+"${AR}" -r tx.a tx_thread_create.o tx_thread_delete.o tx_thread_entry_exit_notify.o tx_thread_identify.o tx_thread_info_get.o tx_thread_initialize.o
+"${AR}" -r tx.a tx_thread_performance_info_get.o tx_thread_performance_system_info_get.o tx_thread_preemption_change.o tx_thread_priority_change.o tx_thread_relinquish.o
+"${AR}" -r tx.a tx_thread_reset.o tx_thread_resume.o tx_thread_shell_entry.o tx_thread_sleep.o tx_thread_stack_analyze.o tx_thread_stack_error_handler.o
+"${AR}" -r tx.a tx_thread_stack_error_notify.o tx_thread_suspend.o tx_thread_system_preempt_check.o tx_thread_system_resume.o tx_thread_system_suspend.o
+"${AR}" -r tx.a tx_thread_terminate.o tx_thread_time_slice.o tx_thread_time_slice_change.o tx_thread_timeout.o tx_thread_wait_abort.o tx_time_get.o
+"${AR}" -r tx.a tx_time_set.o tx_timer_activate.o tx_timer_change.o tx_timer_create.o tx_timer_deactivate.o tx_timer_delete.o tx_timer_expiration_process.o
+"${AR}" -r tx.a tx_timer_info_get.o tx_timer_initialize.o tx_timer_performance_info_get.o tx_timer_performance_system_info_get.o tx_timer_system_activate.o
+"${AR}" -r tx.a tx_timer_system_deactivate.o tx_timer_thread_entry.o tx_trace_enable.o tx_trace_disable.o tx_trace_initialize.o tx_trace_interrupt_control.o
+"${AR}" -r tx.a tx_trace_isr_enter_insert.o tx_trace_isr_exit_insert.o tx_trace_object_register.o tx_trace_object_unregister.o tx_trace_user_event_insert.o
+"${AR}" -r tx.a tx_trace_buffer_full_notify.o tx_trace_event_filter.o tx_trace_event_unfilter.o
+"${AR}" -r tx.a txe_block_allocate.o txe_block_pool_create.o txe_block_pool_delete.o txe_block_pool_info_get.o txe_block_pool_prioritize.o txe_block_release.o
+"${AR}" -r tx.a txe_byte_allocate.o txe_byte_pool_create.o txe_byte_pool_delete.o txe_byte_pool_info_get.o txe_byte_pool_prioritize.o txe_byte_release.o
+"${AR}" -r tx.a txe_event_flags_create.o txe_event_flags_delete.o txe_event_flags_get.o txe_event_flags_info_get.o txe_event_flags_set.o
+"${AR}" -r tx.a txe_event_flags_set_notify.o txe_mutex_create.o txe_mutex_delete.o txe_mutex_get.o txe_mutex_info_get.o txe_mutex_prioritize.o
+"${AR}" -r tx.a txe_mutex_put.o txe_queue_create.o txe_queue_delete.o txe_queue_flush.o txe_queue_front_send.o txe_queue_info_get.o txe_queue_prioritize.o
+"${AR}" -r tx.a txe_queue_receive.o txe_queue_send.o txe_queue_send_notify.o txe_semaphore_ceiling_put.o txe_semaphore_create.o txe_semaphore_delete.o
+"${AR}" -r tx.a txe_semaphore_get.o txe_semaphore_info_get.o txe_semaphore_prioritize.o txe_semaphore_put.o txe_semaphore_put_notify.o txe_thread_create.o
+"${AR}" -r tx.a txe_thread_delete.o txe_thread_entry_exit_notify.o txe_thread_info_get.o txe_thread_preemption_change.o txe_thread_priority_change.o
+"${AR}" -r tx.a txe_thread_relinquish.o txe_thread_reset.o txe_thread_resume.o txe_thread_suspend.o txe_thread_terminate.o txe_thread_time_slice_change.o
+"${AR}" -r tx.a txe_thread_wait_abort.o txe_timer_activate.o txe_timer_change.o txe_timer_create.o txe_timer_deactivate.o txe_timer_delete.o txe_timer_info_get.o
+"${AR}" -r tx.a tx_thread_smp_current_state_set.o tx_thread_smp_debug_entry_insert.o tx_thread_smp_high_level_initialize.o
+"${AR}" -r tx.a tx_thread_smp_rebalance_execute_list.o tx_thread_smp_core_exclude.o tx_thread_smp_core_exclude_get.o
+"${AR}" -r tx.a tx_timer_smp_core_exclude.o tx_timer_smp_core_exclude_get.o tx_thread_smp_utilities.o
+"${AR}" -r tx.a tx_thread_smp_core_get.o tx_thread_smp_core_preempt.o tx_thread_smp_current_state_get.o tx_thread_smp_current_thread_get.o tx_thread_smp_initialize_wait.o
+"${AR}" -r tx.a tx_thread_smp_low_level_initialize.o tx_thread_smp_protect.o tx_thread_smp_time_get.o tx_thread_smp_unprotect.o
diff --git a/ports_smp/cortex_a9_smp/gnu/example_build/build_threadx_sample.sh b/ports_smp/cortex_a9_smp/gnu/example_build/build_threadx_sample.sh
new file mode 100755
index 00000000..42987622
--- /dev/null
+++ b/ports_smp/cortex_a9_smp/gnu/example_build/build_threadx_sample.sh
@@ -0,0 +1,54 @@
+#!/bin/sh
+##############################################################################
+# 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.
+#
+# SPDX-License-Identifier: MIT
+##############################################################################
+
+set -e
+cd "$(dirname "$0")"
+
+# this script builds the ThreadX sample image for the Cortex-A9 SMP port using
+# GNU toolchain or llvm/clang toolchain (defaults to GNU).
+: "${TOOLCHAIN:=gnu}"
+case "${TOOLCHAIN}" in
+ gnu)
+ CC="arm-none-eabi-gcc"
+ TARGET_FLAGS="" # GNU and Clang use different driver syntax for selecting the program's
+ # entry-point symbol.
+ ENTRY_FLAG="-e Vectors"
+ # Bare-metal C libraries require syscall support. GNU uses newlib's nosys stubs
+ # while ATFE requires a semihost library.
+ SYSCALL_LIB="--specs=nosys.specs"
+ ;;
+ atfe)
+ CC="${ATFE_CLANG:-clang}"
+ TARGET_FLAGS="--target=arm-none-eabi"
+ ENTRY_FLAG="-Wl,--entry=Vectors"
+ SYSCALL_LIB="-lsemihost"
+ ;;
+ *)
+ echo "Unknown TOOLCHAIN: ${TOOLCHAIN}" >&2
+ exit 1
+ ;;
+esac
+
+"${CC}" ${TARGET_FLAGS} -c -g -I../../../../common_smp/inc -I../inc -mcpu=cortex-a9 sample_threadx.c
+"${CC}" ${TARGET_FLAGS} -c -g -mcpu=cortex-a9 startup.S
+"${CC}" ${TARGET_FLAGS} -c -g -mcpu=cortex-a9 crt0.S
+"${CC}" ${TARGET_FLAGS} -c -g -mcpu=cortex-a9 MP_GIC.S
+"${CC}" ${TARGET_FLAGS} -c -g -mcpu=cortex-a9 MP_SCU.S
+"${CC}" ${TARGET_FLAGS} -c -g -mcpu=cortex-a9 MP_Mutexes.S
+"${CC}" ${TARGET_FLAGS} -c -g -mcpu=cortex-a9 MP_PrivateTimer.S
+"${CC}" ${TARGET_FLAGS} -c -g -mcpu=cortex-a9 v7.S
+"${CC}" ${TARGET_FLAGS} -g -mcpu=cortex-a9 -nostartfiles \
+ -T sample_threadx.ld \
+ ${ENTRY_FLAG} \
+ ${SYSCALL_LIB} \
+ -o sample_threadx.out MP_PrivateTimer.o MP_GIC.o MP_Mutexes.o MP_SCU.o \
+ sample_threadx.o startup.o crt0.o v7.o tx.a \
+ -Wl,-M > sample_threadx.map
diff --git a/ports_smp/cortex_a9_smp/gnu/example_build/crt0.S b/ports_smp/cortex_a9_smp/gnu/example_build/crt0.S
new file mode 100644
index 00000000..abc817d5
--- /dev/null
+++ b/ports_smp/cortex_a9_smp/gnu/example_build/crt0.S
@@ -0,0 +1,101 @@
+
+ .syntax unified
+#if defined(THUMB_MODE)
+ .thumb
+#else
+ .arm
+#endif
+
+/* .text is used instead of .section .text so it works with arm-aout too. */
+ .text
+ .align 0
+
+#if defined(THUMB_MODE)
+ .thumb_func
+#endif
+ .global _mainCRTStartup
+_mainCRTStartup:
+#if defined(THUMB_MODE)
+ .thumb_func
+#endif
+ .global _start
+_start:
+#if defined(THUMB_MODE)
+ .thumb_func
+#endif
+ .global start
+start:
+
+/* Start by setting up a stack */
+ /* Set up the stack pointer to a fixed value */
+ ldr r3, .LC0
+ mov sp, r3
+ /* Setup a default stack-limit in case the code has been
+ compiled with "-mapcs-stack-check". Hard-wiring this value
+ is not ideal, since there is currently no support for
+ checking that the heap and stack have not collided, or that
+ this default 64k is enough for the program being executed.
+ However, it ensures that this simple crt0 world will not
+ immediately cause an overflow event: */
+ sub sl, sp, #64 << 10 /* Still assumes 256bytes below sl */
+ mov a2, #0 /* Second arg: fill value */
+ mov fp, a2 /* Null frame pointer */
+ mov r7, a2 /* Null frame pointer for Thumb */
+
+ ldr a1, .LC1 /* First arg: start of memory block */
+ ldr a3, .LC2
+ sub a3, a3, a1 /* Third arg: length of block */
+
+
+
+ bl memset
+ mov r0, #0 /* no arguments */
+ mov r1, #0 /* no argv either */
+#ifdef __USES_INITFINI__
+ /* Some arm/elf targets use the .init and .fini sections
+ to create constructors and destructors, and for these
+ targets we need to call the _init function and arrange
+ for _fini to be called at program exit. */
+ mov r4, r0
+ mov r5, r1
+/* ldr r0, .Lfini */
+ bl atexit
+/* bl init */
+ mov r0, r4
+ mov r1, r5
+#endif
+ bl main
+
+ bl exit /* Should not return. */
+
+
+ /* For Thumb, constants must be after the code since only
+ positive offsets are supported for PC relative addresses. */
+
+ .align 0
+.LC0:
+.LC1:
+ .word __bss_start__
+.LC2:
+ .word __bss_end__
+/*
+#ifdef __USES_INITFINI__
+.Lfini:
+ .word _fini
+#endif */
+ /* Return ... */
+ bx lr
+
+ .global _fini
+ .type _fini,function
+_fini:
+ BX lr // Return to caller
+
+/* Workspace for Angel calls. */
+ .data
+/* Data returned by monitor SWI. */
+.global __stack_base__
+HeapBase: .word 0
+HeapLimit: .word 0
+__stack_base__: .word 0
+StackLimit: .word 0
diff --git a/ports_smp/cortex_a9_smp/gnu/inc/tx_port.h b/ports_smp/cortex_a9_smp/gnu/inc/tx_port.h
index c43fcb7a..56497057 100644
--- a/ports_smp/cortex_a9_smp/gnu/inc/tx_port.h
+++ b/ports_smp/cortex_a9_smp/gnu/inc/tx_port.h
@@ -386,7 +386,7 @@ void tx_thread_vfp_disable(void);
#ifdef TX_THREAD_INIT
CHAR _tx_version_id[] =
- "(c) 2024 Microsoft Corp. (c) 2026-present Eclipse ThreadX contributors. * ThreadX SMP/Cortex-A9/GNU Version Version 6.5.1.202602a *";
+ "(c) 2024 Microsoft Corp. (c) 2026-present Eclipse ThreadX contributors. * ThreadX SMP/Cortex-A9/GNU Version Version 6.5.2.202603 *";
#else
extern CHAR _tx_version_id[];
#endif
diff --git a/ports_smp/cortex_a9_smp/gnu/src/tx_thread_context_restore.S b/ports_smp/cortex_a9_smp/gnu/src/tx_thread_context_restore.S
index 2fbf25fd..c09d258d 100644
--- a/ports_smp/cortex_a9_smp/gnu/src/tx_thread_context_restore.S
+++ b/ports_smp/cortex_a9_smp/gnu/src/tx_thread_context_restore.S
@@ -1,5 +1,6 @@
@/***************************************************************************
@ * Copyright (c) 2024 Microsoft Corporation
+@ * 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
@@ -7,6 +8,7 @@
@ *
@ * SPDX-License-Identifier: MIT
@ **************************************************************************/
+@ Portions of this file were generated with AI assistance.
@
@
@/**************************************************************************/
@@ -29,8 +31,6 @@
@#include "tx_thread.h"
@#include "tx_timer.h"
@
-@/* Include macros for modifying the wait list. */
-#include "tx_thread_smp_protection_wait_list_macros.h"
#ifdef TX_ENABLE_FIQ_SUPPORT
DISABLE_INTS = 0xC0 @ Disable IRQ & FIQ interrupts
@@ -51,11 +51,6 @@ SVC_MODE = 0x93 @ SVC mode
.global _tx_thread_preempt_disable
.global _tx_timer_interrupt_active
.global _tx_thread_smp_protection
- .global _tx_thread_smp_protect_wait_counts
- .global _tx_thread_smp_protect_wait_list
- .global _tx_thread_smp_protect_wait_list_lock_protect_in_force
- .global _tx_thread_smp_protect_wait_list_tail
- .global _tx_thread_smp_protect_wait_list_size
#ifdef TX_ENABLE_EXECUTION_CHANGE_NOTIFY
.global _tx_execution_isr_exit
#endif
@@ -198,77 +193,6 @@ __tx_thread_no_preempt_restore:
@ {
@
__tx_thread_preempt_restore:
-@
-@ /* Was the thread being preempted waiting for the lock? */
-@ if (_tx_thread_smp_protect_wait_counts[this_core] != 0)
-@ {
-@
- LDR r1, =_tx_thread_smp_protect_wait_counts @ Load waiting count list
- LDR r2, [r1, r10, LSL #2] @ Load waiting value for this core
- CMP r2, #0
- BEQ _nobody_waiting_for_lock @ Is the core waiting for the lock?
-@
-@ /* Do we not have the lock? This means the ISR never got the inter-core lock. */
-@ if (_tx_thread_smp_protection.tx_thread_smp_protect_owned != this_core)
-@ {
-@
- LDR r1, =_tx_thread_smp_protection @ Load address of protection structure
- LDR r2, [r1, #8] @ Pickup the owning core
- CMP r10, r2 @ Compare our core to the owning core
- BEQ _this_core_has_lock @ Do we have the lock?
-@
-@ /* We don't have the lock. This core should be in the list. Remove it. */
-@ _tx_thread_smp_protect_wait_list_remove(this_core);
-@
- MOV r0, r10 @ Move the core ID to r0 for the macro
- _tx_thread_smp_protect_wait_list_remove @ Call macro to remove core from the list
- B _nobody_waiting_for_lock @ Leave
-@
-@ }
-@ else
-@ {
-@ /* We have the lock. This means the ISR got the inter-core lock, but
-@ never released it because it saw that there was someone waiting.
-@ Note this core is not in the list. */
-@
-_this_core_has_lock:
-@
-@ /* We're no longer waiting. Note that this should be zero since this happens during thread preemption. */
-@ _tx_thread_smp_protect_wait_counts[core]--;
-@
- LDR r1, =_tx_thread_smp_protect_wait_counts @ Load waiting count list
- LDR r2, [r1, r10, LSL #2] @ Load waiting value for this core
- SUB r2, r2, #1 @ Decrement waiting value. Should be zero now
- STR r2, [r1, r10, LSL #2] @ Store new waiting value
-@
-@ /* Now release the inter-core lock. */
-@
-@ /* Set protected core as invalid. */
-@ _tx_thread_smp_protection.tx_thread_smp_protect_core = 0xFFFFFFFF;
-@
- LDR r1, =_tx_thread_smp_protection @ Load address of protection structure
- MOV r2, #0xFFFFFFFF @ Build invalid value
- STR r2, [r1, #8] @ Mark the protected core as invalid
- DMB @ Ensure that accesses to shared resource have completed
-@
-@ /* Release protection. */
-@ _tx_thread_smp_protection.tx_thread_smp_protect_in_force = 0;
-@
- MOV r2, #0 @ Build release protection value
- STR r2, [r1, #0] @ Release the protection
- DSB ISH @ To ensure update of the protection occurs before other CPUs awake
-@
-@ /* Wake up waiting processors. Note interrupts are already enabled. */
-@
-#ifdef TX_ENABLE_WFE
- SEV @ Send event to other CPUs
-#endif
-@
-@ }
-@ }
-@
-
-_nobody_waiting_for_lock:
LDMIA sp!, {r3, r10, r12, lr} @ Recover temporarily saved registers
MOV r1, lr @ Save lr (point of interrupt)
diff --git a/ports_smp/cortex_a9_smp/gnu/src/tx_thread_context_save.S b/ports_smp/cortex_a9_smp/gnu/src/tx_thread_context_save.S
index ae4065c4..2cef910d 100644
--- a/ports_smp/cortex_a9_smp/gnu/src/tx_thread_context_save.S
+++ b/ports_smp/cortex_a9_smp/gnu/src/tx_thread_context_save.S
@@ -1,5 +1,6 @@
@/***************************************************************************
@ * Copyright (c) 2024 Microsoft Corporation
+@ * Copyright (c) 2026-present Eclipse ThreadX contributors
@ *
@ * This program and the accompanying materials are made available under the
@ * terms of the MIT License which is available at
@@ -8,6 +9,7 @@
@ * SPDX-License-Identifier: MIT
@ **************************************************************************/
@
+@ Portions of this file were generated with AI assistance.
@
@/**************************************************************************/
@/**************************************************************************/
@@ -147,11 +149,11 @@ __tx_thread_not_nested_save:
BEQ __tx_thread_idle_system_save @ If so, interrupt occurred in
@ scheduling loop - nothing needs saving!
@
-@ /* Save the current stack pointer in the thread's control block. */
-@ _tx_thread_current_ptr[core] -> tx_thread_stack_ptr = sp;
-@
-@ /* Switch to the system stack. */
-@ sp = _tx_thread_system_stack_ptr;
+@ /* This routine runs in IRQ mode on this core's banked IRQ stack, which
+@ serves as the system stack on this architecture, so there is no stack
+@ switch to perform here. The thread's stack pointer is saved in its
+@ control block by _tx_thread_context_restore, and only when the
+@ interrupt results in preemption. */
@
MOV r10, #0 @ Clear stack limit
diff --git a/ports_smp/cortex_a9_smp/gnu/src/tx_thread_schedule.S b/ports_smp/cortex_a9_smp/gnu/src/tx_thread_schedule.S
index 84fec67d..3e8a41e6 100644
--- a/ports_smp/cortex_a9_smp/gnu/src/tx_thread_schedule.S
+++ b/ports_smp/cortex_a9_smp/gnu/src/tx_thread_schedule.S
@@ -1,5 +1,6 @@
@/***************************************************************************
@ * Copyright (c) 2024 Microsoft Corporation
+@ * 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
@@ -8,6 +9,8 @@
@ * SPDX-License-Identifier: MIT
@ **************************************************************************/
@
+@ Portions of this file were generated with AI assistance.
+@
@
@/**************************************************************************/
@/**************************************************************************/
@@ -165,6 +168,7 @@ _tx_thread_ready_for_execution:
LDR r2, =_tx_thread_current_ptr @ Pickup address of current thread
ADD r2, r2, r12 @ Build index into the current thread array
STR r0, [r2, #0] @ Setup current thread pointer
+ DMB @ Ensure the current thread pointer write completes
@
@ /* In the time between reading the execute pointer and assigning
@ it to the current pointer, the execute pointer was changed by
diff --git a/ports_smp/cortex_a9_smp/gnu/src/tx_thread_smp_protect.S b/ports_smp/cortex_a9_smp/gnu/src/tx_thread_smp_protect.S
index e90f73e2..9a3838f1 100644
--- a/ports_smp/cortex_a9_smp/gnu/src/tx_thread_smp_protect.S
+++ b/ports_smp/cortex_a9_smp/gnu/src/tx_thread_smp_protect.S
@@ -1,5 +1,6 @@
@/***************************************************************************
@ * Copyright (c) 2024 Microsoft Corporation
+@ * 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
@@ -7,6 +8,7 @@
@ *
@ * SPDX-License-Identifier: MIT
@ **************************************************************************/
+@ Portions of this file were generated with AI assistance.
@
@
@/**************************************************************************/
@@ -31,17 +33,9 @@
@
@
-@/* Include macros for modifying the wait list. */
-#include "tx_thread_smp_protection_wait_list_macros.h"
.global _tx_thread_current_ptr
.global _tx_thread_smp_protection
- .global _tx_thread_smp_protect_wait_counts
- .global _tx_thread_smp_protect_wait_list
- .global _tx_thread_smp_protect_wait_list_lock_protect_in_force
- .global _tx_thread_smp_protect_wait_list_head
- .global _tx_thread_smp_protect_wait_list_tail
- .global _tx_thread_smp_protect_wait_list_size
.arm
.text
@@ -85,11 +79,9 @@ _tx_thread_smp_protect:
@VOID _tx_thread_smp_protect(VOID)
@{
@
- PUSH {r4-r6} @ Save registers we'll be using
-@
@ /* Disable interrupts so we don't get preempted. */
@
- MRS r0, CPSR @ Pickup current CPSR
+ MRS r3, CPSR @ Pickup current CPSR
#ifdef TX_ENABLE_FIQ_SUPPORT
CPSID if @ Disable IRQ and FIQ interrupts
@@ -97,270 +89,96 @@ _tx_thread_smp_protect:
CPSID i @ Disable IRQ interrupts
#endif
@
+@ /* Pickup the CPU ID. */
+@
+ MRC p15, 0, r2, c0, c0, 5 @ Read CPU ID register
+ AND r2, r2, #0x03 @ Mask off, leaving the CPU ID field
+@
@ /* Do we already have protection? */
@ if (this_core == _tx_thread_smp_protection.tx_thread_smp_protect_core)
@ {
@
- MRC p15, 0, r1, c0, c0, 5 @ Read CPU ID register
- AND r1, r1, #0x03 @ Mask off, leaving the CPU ID field
- LDR r2, =_tx_thread_smp_protection @ Build address to protection structure
- LDR r3, [r2, #8] @ Pickup the owning core
- CMP r1, r3 @ Is it not this core?
- BNE _protection_not_owned @ No, the protection is not already owned
-@
-@ /* We already have protection. */
-@
-@ /* Increment the protection count. */
-@ _tx_thread_smp_protection.tx_thread_smp_protect_count++;
+ LDR r0, =_tx_thread_smp_protection @ Build address to protection structure
+ LDR r1, [r0, #8] @ Pickup the owning core
+ CMP r1, r2 @ Is it this core?
+ BEQ _owned @ Yes, the protection is already owned
@
- LDR r3, [r2, #12] @ Pickup ownership count
- ADD r3, r3, #1 @ Increment ownership count
- STR r3, [r2, #12] @ Store ownership count
- DMB
-
- B _return
-
-_protection_not_owned:
+@ }
@
@ /* Is the lock available? */
@ if (_tx_thread_smp_protection.tx_thread_smp_protect_in_force == 0)
@ {
@
- LDREX r3, [r2, #0] @ Pickup the protection flag
- CMP r3, #0
- BNE _start_waiting @ No, protection not available
-@
-@ /* Is the list empty? */
-@ if (_tx_thread_smp_protect_wait_list_head == _tx_thread_smp_protect_wait_list_tail)
-@ {
-@
- LDR r3, =_tx_thread_smp_protect_wait_list_head
- LDR r3, [r3]
- LDR r4, =_tx_thread_smp_protect_wait_list_tail
- LDR r4, [r4]
- CMP r3, r4
- BNE _list_not_empty
-@
-@ /* Try to get the lock. */
-@ if (write_exclusive(&_tx_thread_smp_protection.tx_thread_smp_protect_in_force, 1) == SUCCESS)
-@ {
-@
- MOV r3, #1 @ Build lock value
- STREX r4, r3, [r2, #0] @ Attempt to get the protection
- CMP r4, #0
- BNE _start_waiting @ Did it fail?
-@
-@ /* We got the lock! */
-@ _tx_thread_smp_protect_lock_got();
-@
- DMB @ Ensure write to protection finishes
- _tx_thread_smp_protect_lock_got @ Call the lock got function
-
- B _return
-
-_list_not_empty:
-@
-@ /* Are we at the front of the list? */
-@ if (this_core == _tx_thread_smp_protect_wait_list[_tx_thread_smp_protect_wait_list_head])
-@ {
-@
- LDR r3, =_tx_thread_smp_protect_wait_list_head @ Get the address of the head
- LDR r3, [r3] @ Get the value of the head
- LDR r4, =_tx_thread_smp_protect_wait_list @ Get the address of the list
- LDR r4, [r4, r3, LSL #2] @ Get the value at the head index
-
- CMP r1, r4
- BNE _start_waiting
-@
-@ /* Is the lock still available? */
-@ if (_tx_thread_smp_protection.tx_thread_smp_protect_in_force == 0)
-@ {
-@
- LDR r3, [r2, #0] @ Pickup the protection flag
- CMP r3, #0
- BNE _start_waiting @ No, protection not available
-@
-@ /* Get the lock. */
-@ _tx_thread_smp_protection.tx_thread_smp_protect_in_force = 1;
-@
- MOV r3, #1 @ Build lock value
- STR r3, [r2, #0] @ Store lock value
- DMB @
-@
-@ /* Got the lock. */
-@ _tx_thread_smp_protect_lock_got();
-@
- _tx_thread_smp_protect_lock_got
-@
-@ /* Remove this core from the wait list. */
-@ _tx_thread_smp_protect_remove_from_front_of_list();
-@
- _tx_thread_smp_protect_remove_from_front_of_list
-
- B _return
-
-_start_waiting:
-@
-@ /* For one reason or another, we didn't get the lock. */
-@
-@ /* Increment wait count. */
-@ _tx_thread_smp_protect_wait_counts[this_core]++;
-@
- LDR r3, =_tx_thread_smp_protect_wait_counts @ Load wait list counts
- LDR r4, [r3, r1, LSL #2] @ Load waiting value for this core
- ADD r4, r4, #1 @ Increment wait value
- STR r4, [r3, r1, LSL #2] @ Store new wait value
-@
-@ /* Have we not added ourselves to the list yet? */
-@ if (_tx_thread_smp_protect_wait_counts[this_core] == 1)
-@ {
-@
- CMP r4, #1
- BNE _already_in_list0 @ Is this core already waiting?
-@
-@ /* Add ourselves to the list. */
-@ _tx_thread_smp_protect_wait_list_add(this_core);
-@
- _tx_thread_smp_protect_wait_list_add @ Call macro to add ourselves to the list
+ LDREX r1, [r0] @ Pickup the protection flag
+ CMP r1, #0 @ Is it available?
+ BEQ _get_protection @ Yes, attempt to get the protection
@
@ }
@
-_already_in_list0:
-@
-@ /* Restore interrupts. */
+@ /* The protection is held elsewhere. Restore interrupts so this core can be
+@ preempted while it waits, then try the whole sequence again. */
@
- MSR CPSR_c, r0 @ Restore CPSR
+ MSR CPSR_c, r3 @ Restore CPSR
#ifdef TX_ENABLE_WFE
WFE @ Go into standby
#endif
-@
-@ /* We do this until we have the lock. */
-@ while (1)
-@ {
-@
-_try_to_get_lock:
-@
-@ /* Disable interrupts so we don't get preempted. */
-@
-#ifdef TX_ENABLE_FIQ_SUPPORT
- CPSID if @ Disable IRQ and FIQ interrupts
-#else
- CPSID i @ Disable IRQ interrupts
-#endif
+ B _tx_thread_smp_protect @ On waking, restart the protection attempt
- MRC p15, 0, r1, c0, c0, 5 @ Read CPU ID register
- AND r1, r1, #0x03 @ Mask off, leaving the CPU ID field
+_get_protection:
@
-@ /* Do we already have protection? */
-@ if (this_core == _tx_thread_smp_protection.tx_thread_smp_protect_core)
+@ /* Try to get the lock. */
+@ if (write_exclusive(&_tx_thread_smp_protection.tx_thread_smp_protect_in_force, 1) == SUCCESS)
@ {
@
- LDR r3, [r2, #8] @ Pickup the owning core
- CMP r3, r1 @ Is it this core?
- BEQ _got_lock_after_waiting @ Yes, the protection is already owned. This means
- @ an ISR preempted us and got protection
+ MOV r1, #1 @ Build lock value
+ STREX r2, r1, [r0] @ Attempt to get the protection
+ CMP r2, #0 @ Check whether the store succeeded (0 = success)
+ BEQ _got_protection @ Yes, we have the protection
@
@ }
@
-@ /* Are we at the front of the list? */
-@ if (this_core == _tx_thread_smp_protect_wait_list[_tx_thread_smp_protect_wait_list_head])
-@ {
+@ /* Another core beat us to it. Restore interrupts and try again. */
@
- LDR r3, =_tx_thread_smp_protect_wait_list_head @ Get the address of the head
- LDR r3, [r3] @ Get the value of the head
- LDR r4, =_tx_thread_smp_protect_wait_list @ Get the address of the list
- LDR r4, [r4, r3, LSL #2] @ Get the value at the head index
+ MSR CPSR_c, r3 @ Restore CPSR
+ B _tx_thread_smp_protect @ Try the whole process again
- CMP r1, r4
- BNE _did_not_get_lock
-@
-@ /* Is the lock still available? */
-@ if (_tx_thread_smp_protection.tx_thread_smp_protect_in_force == 0)
-@ {
-@
- LDR r3, [r2, #0] @ Pickup the protection flag
- CMP r3, #0
- BNE _did_not_get_lock @ No, protection not available
-@
-@ /* Get the lock. */
-@ _tx_thread_smp_protection.tx_thread_smp_protect_in_force = 1;
-@
- MOV r3, #1 @ Build lock value
- STR r3, [r2, #0] @ Store lock value
- DMB @
+_got_protection:
@
-@ /* Got the lock. */
-@ _tx_thread_smp_protect_lock_got();
+@ /* Got the lock. Record the owning core. */
+@ _tx_thread_smp_protection.tx_thread_smp_protect_core = this_core;
@
- _tx_thread_smp_protect_lock_got
-@
-@ /* Remove this core from the wait list. */
-@ _tx_thread_smp_protect_remove_from_front_of_list();
-@
- _tx_thread_smp_protect_remove_from_front_of_list
-
- B _got_lock_after_waiting
+ DMB @ Ensure the protection write completes before it is used
+ MRC p15, 0, r2, c0, c0, 5 @ Read CPU ID register
+ AND r2, r2, #0x03 @ Mask off, leaving the CPU ID field
+ STR r2, [r0, #8] @ Save the owning core
-_did_not_get_lock:
-@
-@ /* For one reason or another, we didn't get the lock. */
-@
-@ /* Were we removed from the list? This can happen if we're a thread
-@ and we got preempted. */
-@ if (_tx_thread_smp_protect_wait_counts[this_core] == 0)
-@ {
-@
- LDR r3, =_tx_thread_smp_protect_wait_counts @ Load wait list counts
- LDR r4, [r3, r1, LSL #2] @ Load waiting value for this core
- CMP r4, #0
- BNE _already_in_list1 @ Is this core already in the list?
-@
-@ /* Add ourselves to the list. */
-@ _tx_thread_smp_protect_wait_list_add(this_core);
-@
- _tx_thread_smp_protect_wait_list_add @ Call macro to add ourselves to the list
-@
-@ /* Our waiting count was also reset when we were preempted. Increment it again. */
-@ _tx_thread_smp_protect_wait_counts[this_core]++;
-@
- LDR r3, =_tx_thread_smp_protect_wait_counts @ Load wait list counts
- LDR r4, [r3, r1, LSL #2] @ Load waiting value for this core
- ADD r4, r4, #1 @ Increment wait value
- STR r4, [r3, r1, LSL #2] @ Store new wait value value
-@
-@ }
-@
-_already_in_list1:
-@
-@ /* Restore interrupts and try again. */
-@
- MSR CPSR_c, r0 @ Restore CPSR
-#ifdef TX_ENABLE_WFE
- WFE @ Go into standby
+#ifdef TX_MPCORE_DEBUG_ENABLE
+ LSL r2, r2, #2 @ Build offset to array indexes
+ LDR r1, =_tx_thread_current_ptr @ Pickup start of the current thread array
+ ADD r1, r1, r2 @ Build index into the current thread array
+ LDR r2, [r1] @ Pickup current thread for this core
+ STR r2, [r0, #4] @ Save current thread pointer
+ STR LR, [r0, #16] @ Save caller's return address
+ STR r3, [r0, #20] @ Save CPSR
#endif
- B _try_to_get_lock @ On waking, restart the protection attempt
-_got_lock_after_waiting:
+_owned:
@
-@ /* We're no longer waiting. */
-@ _tx_thread_smp_protect_wait_counts[this_core]--;
+@ /* Increment the protection count. */
+@ _tx_thread_smp_protection.tx_thread_smp_protect_count++;
@
- LDR r3, =_tx_thread_smp_protect_wait_counts @ Load waiting list
- LDR r4, [r3, r1, LSL #2] @ Load current wait value
- SUB r4, r4, #1 @ Decrement wait value
- STR r4, [r3, r1, LSL #2] @ Store new wait value value
+ LDR r1, [r0, #12] @ Pickup ownership count
+ ADD r1, r1, #1 @ Increment ownership count
+ STR r1, [r0, #12] @ Store new ownership count
+ DMB @
+ MOV r0, r3 @ Return the previous CPSR
@
-@ /* Restore link register and return. */
+@}
@
-_return:
-
- POP {r4-r6} @ Restore registers
-
#ifdef __THUMB_INTERWORK
BX lr @ Return to caller
#else
MOV pc, lr @ Return to caller
#endif
-
diff --git a/ports_smp/cortex_a9_smp/gnu/src/tx_thread_smp_protection_wait_list_macros.h b/ports_smp/cortex_a9_smp/gnu/src/tx_thread_smp_protection_wait_list_macros.h
deleted file mode 100644
index f1ad80e8..00000000
--- a/ports_smp/cortex_a9_smp/gnu/src/tx_thread_smp_protection_wait_list_macros.h
+++ /dev/null
@@ -1,309 +0,0 @@
-@/***************************************************************************
-@ * Copyright (c) 2024 Microsoft Corporation
-@ *
-@ * 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.
-@ *
-@ * SPDX-License-Identifier: MIT
-@ **************************************************************************/
-@
-@
-@/**************************************************************************/
-@/**************************************************************************/
-@/** */
-@/** ThreadX Component */
-@/** */
-@/** Thread - Low Level SMP Support */
-@/** */
-@/**************************************************************************/
-@/**************************************************************************/
-
- .macro _tx_thread_smp_protect_lock_got
-@
-@ /* Set the currently owned core. */
-@ _tx_thread_smp_protection.tx_thread_smp_protect_core = this_core;
-@
- STR r1, [r2, #8] @ Store this core
-@
-@ /* Increment the protection count. */
-@ _tx_thread_smp_protection.tx_thread_smp_protect_count++;
-@
- LDR r3, [r2, #12] @ Pickup ownership count
- ADD r3, r3, #1 @ Increment ownership count
- STR r3, [r2, #12] @ Store ownership count
- DMB
-
-#ifdef TX_MPCORE_DEBUG_ENABLE
- LSL r3, r1, #2 @ Build offset to array indexes
- LDR r4, =_tx_thread_current_ptr @ Pickup start of the current thread array
- ADD r4, r3, r4 @ Build index into the current thread array
- LDR r3, [r4] @ Pickup current thread for this core
- STR r3, [r2, #4] @ Save current thread pointer
- STR LR, [r2, #16] @ Save caller's return address
- STR r0, [r2, #20] @ Save CPSR
-#endif
-
- .endm
-
- .macro _tx_thread_smp_protect_remove_from_front_of_list
-@
-@ /* Remove ourselves from the list. */
-@ _tx_thread_smp_protect_wait_list[_tx_thread_smp_protect_wait_list_head++] = 0xFFFFFFFF;
-@
- MOV r3, #0xFFFFFFFF @ Build the invalid core value
- LDR r4, =_tx_thread_smp_protect_wait_list_head @ Get the address of the head
- LDR r5, [r4] @ Get the value of the head
- LDR r6, =_tx_thread_smp_protect_wait_list @ Get the address of the list
- STR r3, [r6, r5, LSL #2] @ Store the invalid core value
- ADD r5, r5, #1 @ Increment the head
-@
-@ /* Did we wrap? */
-@ if (_tx_thread_smp_protect_wait_list_head == TX_THREAD_SMP_MAX_CORES + 1)
-@ {
-@
- LDR r3, =_tx_thread_smp_protect_wait_list_size @ Load address of core list size
- LDR r3, [r3] @ Load the max cores value
- CMP r5, r3 @ Compare the head to it
- BNE _store_new_head\@ @ Are we at the max?
-@
-@ _tx_thread_smp_protect_wait_list_head = 0;
-@
- EOR r5, r5, r5 @ We're at the max. Set it to zero
-@
-@ }
-@
-_store_new_head\@:
-
- STR r5, [r4] @ Store the new head
-@
-@ /* We have the lock! */
-@ return;
-@
- .endm
-
-
- .macro _tx_thread_smp_protect_wait_list_lock_get
-@VOID _tx_thread_smp_protect_wait_list_lock_get()
-@{
-@ /* We do this until we have the lock. */
-@ while (1)
-@ {
-@
-_tx_thread_smp_protect_wait_list_lock_get__try_to_get_lock\@:
-@
-@ /* Is the list lock available? */
-@ _tx_thread_smp_protect_wait_list_lock_protect_in_force = load_exclusive(&_tx_thread_smp_protect_wait_list_lock_protect_in_force);
-@
- LDR r1, =_tx_thread_smp_protect_wait_list_lock_protect_in_force
- LDREX r2, [r1] @ Pickup the protection flag
-@
-@ if (protect_in_force == 0)
-@ {
-@
- CMP r2, #0
- BNE _tx_thread_smp_protect_wait_list_lock_get__try_to_get_lock\@ @ No, protection not available
-@
-@ /* Try to get the list. */
-@ int status = store_exclusive(&_tx_thread_smp_protect_wait_list_lock_protect_in_force, 1);
-@
- MOV r2, #1 @ Build lock value
- STREX r3, r2, [r1] @ Attempt to get the protection
-@
-@ if (status == SUCCESS)
-@
- CMP r3, #0
- BNE _tx_thread_smp_protect_wait_list_lock_get__try_to_get_lock\@ @ Did it fail? If so, try again.
-@
-@ /* We have the lock! */
-@ return;
-@
- .endm
-
-
- .macro _tx_thread_smp_protect_wait_list_add
-@VOID _tx_thread_smp_protect_wait_list_add(UINT new_core)
-@{
-@
-@ /* We're about to modify the list, so get the list lock. */
-@ _tx_thread_smp_protect_wait_list_lock_get();
-@
- PUSH {r1-r2}
-
- _tx_thread_smp_protect_wait_list_lock_get
-
- POP {r1-r2}
-@
-@ /* Add this core. */
-@ _tx_thread_smp_protect_wait_list[_tx_thread_smp_protect_wait_list_tail++] = new_core;
-@
- LDR r3, =_tx_thread_smp_protect_wait_list_tail @ Get the address of the tail
- LDR r4, [r3] @ Get the value of tail
- LDR r5, =_tx_thread_smp_protect_wait_list @ Get the address of the list
- STR r1, [r5, r4, LSL #2] @ Store the new core value
- ADD r4, r4, #1 @ Increment the tail
-@
-@ /* Did we wrap? */
-@ if (_tx_thread_smp_protect_wait_list_tail == _tx_thread_smp_protect_wait_list_size)
-@ {
-@
- LDR r5, =_tx_thread_smp_protect_wait_list_size @ Load max cores address
- LDR r5, [r5] @ Load max cores value
- CMP r4, r5 @ Compare max cores to tail
- BNE _tx_thread_smp_protect_wait_list_add__no_wrap\@ @ Did we wrap?
-@
-@ _tx_thread_smp_protect_wait_list_tail = 0;
-@
- MOV r4, #0
-@
-@ }
-@
-_tx_thread_smp_protect_wait_list_add__no_wrap\@:
-
- STR r4, [r3] @ Store the new tail value.
-@
-@ /* Release the list lock. */
-@ _tx_thread_smp_protect_wait_list_lock_protect_in_force = 0;
-@
- MOV r3, #0 @ Build lock value
- LDR r4, =_tx_thread_smp_protect_wait_list_lock_protect_in_force
- STR r3, [r4] @ Store the new value
-
- .endm
-
-
- .macro _tx_thread_smp_protect_wait_list_remove
-@VOID _tx_thread_smp_protect_wait_list_remove(UINT core)
-@{
-@
-@ /* Get the core index. */
-@ UINT core_index;
-@ for (core_index = 0;; core_index++)
-@
- EOR r1, r1, r1 @ Clear for 'core_index'
- LDR r2, =_tx_thread_smp_protect_wait_list @ Get the address of the list
-@
-@ {
-@
-_tx_thread_smp_protect_wait_list_remove__check_cur_core\@:
-@
-@ /* Is this the core? */
-@ if (_tx_thread_smp_protect_wait_list[core_index] == core)
-@ {
-@ break;
-@
- LDR r3, [r2, r1, LSL #2] @ Get the value at the current index
- CMP r3, r0 @ Did we find the core?
- BEQ _tx_thread_smp_protect_wait_list_remove__found_core\@
-@
-@ }
-@
- ADD r1, r1, #1 @ Increment cur index
- B _tx_thread_smp_protect_wait_list_remove__check_cur_core\@ @ Restart the loop
-@
-@ }
-@
-_tx_thread_smp_protect_wait_list_remove__found_core\@:
-@
-@ /* We're about to modify the list. Get the lock. We need the lock because another
-@ core could be simultaneously adding (a core is simultaneously trying to get
-@ the inter-core lock) or removing (a core is simultaneously being preempted,
-@ like what is currently happening). */
-@ _tx_thread_smp_protect_wait_list_lock_get();
-@
- PUSH {r1}
-
- _tx_thread_smp_protect_wait_list_lock_get
-
- POP {r1}
-@
-@ /* We remove by shifting. */
-@ while (core_index != _tx_thread_smp_protect_wait_list_tail)
-@ {
-@
-_tx_thread_smp_protect_wait_list_remove__compare_index_to_tail\@:
-
- LDR r2, =_tx_thread_smp_protect_wait_list_tail @ Load tail address
- LDR r2, [r2] @ Load tail value
- CMP r1, r2 @ Compare cur index and tail
- BEQ _tx_thread_smp_protect_wait_list_remove__removed\@
-@
-@ UINT next_index = core_index + 1;
-@
- MOV r2, r1 @ Move current index to next index register
- ADD r2, r2, #1 @ Add 1
-@
-@ if (next_index == _tx_thread_smp_protect_wait_list_size)
-@ {
-@
- LDR r3, =_tx_thread_smp_protect_wait_list_size
- LDR r3, [r3]
- CMP r2, r3
- BNE _tx_thread_smp_protect_wait_list_remove__next_index_no_wrap\@
-@
-@ next_index = 0;
-@
- MOV r2, #0
-@
-@ }
-@
-_tx_thread_smp_protect_wait_list_remove__next_index_no_wrap\@:
-@
-@ list_cores[core_index] = list_cores[next_index];
-@
- LDR r0, =_tx_thread_smp_protect_wait_list @ Get the address of the list
- LDR r3, [r0, r2, LSL #2] @ Get the value at the next index
- STR r3, [r0, r1, LSL #2] @ Store the value at the current index
-@
-@ core_index = next_index;
-@
- MOV r1, r2
-
- B _tx_thread_smp_protect_wait_list_remove__compare_index_to_tail\@
-@
-@ }
-@
-_tx_thread_smp_protect_wait_list_remove__removed\@:
-@
-@ /* Now update the tail. */
-@ if (_tx_thread_smp_protect_wait_list_tail == 0)
-@ {
-@
- LDR r0, =_tx_thread_smp_protect_wait_list_tail @ Load tail address
- LDR r1, [r0] @ Load tail value
- CMP r1, #0
- BNE _tx_thread_smp_protect_wait_list_remove__tail_not_zero\@
-@
-@ _tx_thread_smp_protect_wait_list_tail = _tx_thread_smp_protect_wait_list_size;
-@
- LDR r2, =_tx_thread_smp_protect_wait_list_size
- LDR r1, [r2]
-@
-@ }
-@
-_tx_thread_smp_protect_wait_list_remove__tail_not_zero\@:
-@
-@ _tx_thread_smp_protect_wait_list_tail--;
-@
- SUB r1, r1, #1
- STR r1, [r0] @ Store new tail value
-@
-@ /* Release the list lock. */
-@ _tx_thread_smp_protect_wait_list_lock_protect_in_force = 0;
-@
- MOV r0, #0 @ Build lock value
- LDR r1, =_tx_thread_smp_protect_wait_list_lock_protect_in_force @ Load lock address
- STR r0, [r1] @ Store the new value
-@
-@ /* We're no longer waiting. Note that this should be zero since, again,
-@ this function is only called when a thread preemption is occurring. */
-@ _tx_thread_smp_protect_wait_counts[core]--;
-@
- MRC p15, 0, r0, c0, c0, 5 @ Read CPU ID register
- AND r0, r0, #0x03 @ Mask off, leaving the CPU ID field
- LDR r1, =_tx_thread_smp_protect_wait_counts @ Load wait list counts
- LDR r2, [r1, r0, LSL #2] @ Load waiting value
- SUB r2, r2, #1 @ Subtract 1
- STR r2, [r1, r0, LSL #2] @ Store new waiting value
- .endm
-
diff --git a/ports_smp/cortex_a9_smp/gnu/src/tx_thread_smp_time_get.S b/ports_smp/cortex_a9_smp/gnu/src/tx_thread_smp_time_get.S
index 9cebe0f2..55215b1e 100644
--- a/ports_smp/cortex_a9_smp/gnu/src/tx_thread_smp_time_get.S
+++ b/ports_smp/cortex_a9_smp/gnu/src/tx_thread_smp_time_get.S
@@ -1,5 +1,6 @@
@/***************************************************************************
@ * Copyright (c) 2024 Microsoft Corporation
+@ * Copyright (c) 2026-present Eclipse ThreadX contributors
@ *
@ * This program and the accompanying materials are made available under the
@ * terms of the MIT License which is available at
@@ -8,6 +9,7 @@
@ * SPDX-License-Identifier: MIT
@ **************************************************************************/
@
+@ Portions of this file were generated with AI assistance.
@
@/**************************************************************************/
@/**************************************************************************/
@@ -71,12 +73,10 @@
_tx_thread_smp_time_get:
MRC p15, 4, r0, c15, c0, 0 @ Read periph base address
- LDR r0, [r0, #0x604] @ Read count register
+ LDR r0, [r0, #0x200] @ Read global timer count low register
#ifdef __THUMB_INTERWORK
BX lr @ Return to caller
#else
MOV pc, lr @ Return to caller
#endif
-
-
diff --git a/ports_smp/cortex_a9_smp/gnu/src/tx_thread_smp_unprotect.S b/ports_smp/cortex_a9_smp/gnu/src/tx_thread_smp_unprotect.S
index a76677ec..c4f42dec 100644
--- a/ports_smp/cortex_a9_smp/gnu/src/tx_thread_smp_unprotect.S
+++ b/ports_smp/cortex_a9_smp/gnu/src/tx_thread_smp_unprotect.S
@@ -1,5 +1,6 @@
@/***************************************************************************
@ * Copyright (c) 2024 Microsoft Corporation
+@ * 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
@@ -7,6 +8,7 @@
@ *
@ * SPDX-License-Identifier: MIT
@ **************************************************************************/
+@ Portions of this file were generated with AI assistance.
@
@
@/**************************************************************************/
@@ -33,7 +35,6 @@
.global _tx_thread_current_ptr
.global _tx_thread_smp_protection
.global _tx_thread_preempt_disable
- .global _tx_thread_smp_protect_wait_counts
.arm
.text
@@ -105,10 +106,6 @@ _tx_thread_smp_unprotect:
CMP r3, #0 @ Is the preempt disable flag set?
BNE _still_protected @ Yes, skip the protection release
- LDR r2,=_tx_thread_smp_protect_wait_counts @ Build build address of wait counts
- LDR r3, [r2, r1, LSL #2] @ Pickup wait list value
- CMP r3, #0 @ Are any entities on this core waiting?
- BNE _still_protected @ Yes, skip the protection release
LDR r2,=_tx_thread_smp_protection @ Build address of protection structure
MOV r3, #0xFFFFFFFF @ Build invalid value
diff --git a/ports_smp/cortex_a9_smp/gnu/src/tx_thread_system_return.S b/ports_smp/cortex_a9_smp/gnu/src/tx_thread_system_return.S
index 6feec05b..02738e90 100644
--- a/ports_smp/cortex_a9_smp/gnu/src/tx_thread_system_return.S
+++ b/ports_smp/cortex_a9_smp/gnu/src/tx_thread_system_return.S
@@ -1,5 +1,6 @@
@/***************************************************************************
@ * Copyright (c) 2024 Microsoft Corporation
+@ * Copyright (c) 2026-present Eclipse ThreadX contributors
@ *
@ * This program and the accompanying materials are made available under the
@ * terms of the MIT License which is available at
@@ -8,6 +9,7 @@
@ * SPDX-License-Identifier: MIT
@ **************************************************************************/
@
+@ Portions of this file were generated with AI assistance.
@
@/**************************************************************************/
@/**************************************************************************/
@@ -134,9 +136,10 @@ _tx_skip_solicited_vfp_save:
ADD r2, r2, r12 @ Build index into time-slice array
LDR r1, [r2, #0] @ Pickup current time slice
@
-@ /* Save current stack and switch to system stack. */
+@ /* Save the current stack pointer in the thread's control block. The
+@ scheduler runs on this core's banked SVC mode stack, which the startup
+@ code set up, so there is no stack switch to perform. */
@ _tx_thread_current_ptr[core] -> tx_thread_stack_ptr = sp;
-@ sp = _tx_thread_system_stack_ptr[core];
@
STR sp, [r0, #8] @ Save thread stack pointer
@
diff --git a/ports_smp/cortex_a9_smp/gnu/src/tx_thread_vectored_context_save.S b/ports_smp/cortex_a9_smp/gnu/src/tx_thread_vectored_context_save.S
index 5991c470..f887de91 100644
--- a/ports_smp/cortex_a9_smp/gnu/src/tx_thread_vectored_context_save.S
+++ b/ports_smp/cortex_a9_smp/gnu/src/tx_thread_vectored_context_save.S
@@ -1,5 +1,6 @@
@/***************************************************************************
@ * Copyright (c) 2024 Microsoft Corporation
+@ * Copyright (c) 2026-present Eclipse ThreadX contributors
@ *
@ * This program and the accompanying materials are made available under the
@ * terms of the MIT License which is available at
@@ -8,6 +9,7 @@
@ * SPDX-License-Identifier: MIT
@ **************************************************************************/
@
+@ Portions of this file were generated with AI assistance.
@
@/**************************************************************************/
@/**************************************************************************/
@@ -145,11 +147,11 @@ __tx_thread_not_nested_save:
@
@ /* Note: Minimal context of interrupted thread is already saved. */
@
-@ /* Save the current stack pointer in the thread's control block. */
-@ _tx_thread_current_ptr[core] -> tx_thread_stack_ptr = sp;
-@
-@ /* Switch to the system stack. */
-@ sp = _tx_thread_system_stack_ptr[core];
+@ /* This routine runs in IRQ mode on this core's banked IRQ stack, which
+@ serves as the system stack on this architecture, so there is no stack
+@ switch to perform here. The thread's stack pointer is saved in its
+@ control block by _tx_thread_context_restore, and only when the
+@ interrupt results in preemption. */
@
MOV r10, #0 @ Clear stack limit
diff --git a/ports_smp/cortex_r8_smp/ac5/inc/tx_port.h b/ports_smp/cortex_r8_smp/ac5/inc/tx_port.h
index cc17a732..10743d13 100644
--- a/ports_smp/cortex_r8_smp/ac5/inc/tx_port.h
+++ b/ports_smp/cortex_r8_smp/ac5/inc/tx_port.h
@@ -393,7 +393,7 @@ void tx_thread_vfp_disable(void);
#ifdef TX_THREAD_INIT
CHAR _tx_version_id[] =
- "(c) 2024 Microsoft Corp. (c) 2026-present Eclipse ThreadX contributors. * ThreadX ARMv7-R SMP Version 6.5.1.202602a *";
+ "(c) 2024 Microsoft Corp. (c) 2026-present Eclipse ThreadX contributors. * ThreadX ARMv7-R SMP Version 6.5.2.202603 *";
#else
extern CHAR _tx_version_id[];
#endif
diff --git a/ports_smp/cortex_r8_smp/ac5/src/tx_thread_context_save.s b/ports_smp/cortex_r8_smp/ac5/src/tx_thread_context_save.s
index 780a6b0a..9ce969e2 100644
--- a/ports_smp/cortex_r8_smp/ac5/src/tx_thread_context_save.s
+++ b/ports_smp/cortex_r8_smp/ac5/src/tx_thread_context_save.s
@@ -9,6 +9,7 @@
* SPDX-License-Identifier: MIT
**************************************************************************/
+// Portions of this file were generated with AI assistance.
/**************************************************************************/
/**************************************************************************/
@@ -134,11 +135,11 @@ __tx_thread_not_nested_save
BEQ __tx_thread_idle_system_save // If so, interrupt occurred in
// scheduling loop - nothing needs saving!
- /* Save the current stack pointer in the thread's control block. */
- // _tx_thread_current_ptr[core] -> tx_thread_stack_ptr = sp;
-
- /* Switch to the system stack. */
- // sp = _tx_thread_system_stack_ptr;
+ /* This routine runs in IRQ mode on this core's banked IRQ stack, which
+ serves as the system stack on this architecture, so there is no stack
+ switch to perform here. The thread's stack pointer is saved in its
+ control block by _tx_thread_context_restore, and only when the
+ interrupt results in preemption. */
MOV r10, #0 // Clear stack limit
diff --git a/ports_smp/cortex_r8_smp/ac5/src/tx_thread_smp_time_get.s b/ports_smp/cortex_r8_smp/ac5/src/tx_thread_smp_time_get.s
index a43484d7..11f7f4ff 100644
--- a/ports_smp/cortex_r8_smp/ac5/src/tx_thread_smp_time_get.s
+++ b/ports_smp/cortex_r8_smp/ac5/src/tx_thread_smp_time_get.s
@@ -9,6 +9,7 @@
* SPDX-License-Identifier: MIT
**************************************************************************/
+// Portions of this file were generated with AI assistance.
/**************************************************************************/
/**************************************************************************/
@@ -57,7 +58,7 @@
_tx_thread_smp_time_get
MRC p15, 4, r0, c15, c0, 0 // Read periph base address
- LDR r0, [r0, #0x604] // Read count register
+ LDR r0, [r0, #0x200] // Read global timer count low register
IF {INTER} = {TRUE}
BX lr // Return to caller
diff --git a/ports_smp/cortex_r8_smp/ac5/src/tx_thread_system_return.s b/ports_smp/cortex_r8_smp/ac5/src/tx_thread_system_return.s
index 2280a351..935d88fa 100644
--- a/ports_smp/cortex_r8_smp/ac5/src/tx_thread_system_return.s
+++ b/ports_smp/cortex_r8_smp/ac5/src/tx_thread_system_return.s
@@ -9,6 +9,7 @@
* SPDX-License-Identifier: MIT
**************************************************************************/
+// Portions of this file were generated with AI assistance.
/**************************************************************************/
/**************************************************************************/
@@ -120,9 +121,10 @@ _tx_skip_solicited_vfp_save
ADD r2, r2, r12 // Build index into time-slice array
LDR r1, [r2, #0] // Pickup current time slice
- /* Save current stack and switch to system stack. */
+ /* Save the current stack pointer in the thread's control block. The
+ scheduler runs on this core's banked SVC mode stack, which the startup
+ code set up, so there is no stack switch to perform. */
// _tx_thread_current_ptr[core] -> tx_thread_stack_ptr = sp;
- // sp = _tx_thread_system_stack_ptr[core];
STR sp, [r0, #8] // Save thread stack pointer
diff --git a/ports_smp/cortex_r8_smp/ac5/src/tx_thread_vectored_context_save.s b/ports_smp/cortex_r8_smp/ac5/src/tx_thread_vectored_context_save.s
index c62297e8..dfbe9bc2 100644
--- a/ports_smp/cortex_r8_smp/ac5/src/tx_thread_vectored_context_save.s
+++ b/ports_smp/cortex_r8_smp/ac5/src/tx_thread_vectored_context_save.s
@@ -9,6 +9,7 @@
* SPDX-License-Identifier: MIT
**************************************************************************/
+// Portions of this file were generated with AI assistance.
/**************************************************************************/
/**************************************************************************/
@@ -132,11 +133,11 @@ __tx_thread_not_nested_save
/* Note: Minimal context of interrupted thread is already saved. */
- /* Save the current stack pointer in the thread's control block. */
- // _tx_thread_current_ptr[core] -> tx_thread_stack_ptr = sp;
-
- /* Switch to the system stack. */
- // sp = _tx_thread_system_stack_ptr[core];
+ /* This routine runs in IRQ mode on this core's banked IRQ stack, which
+ serves as the system stack on this architecture, so there is no stack
+ switch to perform here. The thread's stack pointer is saved in its
+ control block by _tx_thread_context_restore, and only when the
+ interrupt results in preemption. */
MOV r10, #0 // Clear stack limit
diff --git a/ports_smp/linux/gnu/CMakeLists.txt b/ports_smp/linux/gnu/CMakeLists.txt
new file mode 100644
index 00000000..7ff9e0a5
--- /dev/null
+++ b/ports_smp/linux/gnu/CMakeLists.txt
@@ -0,0 +1,41 @@
+# Copyright (c) 2026 Eclipse ThreadX contributors
+# SPDX-License-Identifier: MIT
+# Portions of this file were generated with AI assistance.
+#
+# ThreadX port sources for linux, GNU tools.
+
+target_sources(${PROJECT_NAME}
+ PRIVATE
+ # {{BEGIN_TARGET_SOURCES}}
+ ${CMAKE_CURRENT_LIST_DIR}/src/tx_initialize_low_level.c
+ ${CMAKE_CURRENT_LIST_DIR}/src/tx_thread_context_restore.c
+ ${CMAKE_CURRENT_LIST_DIR}/src/tx_thread_context_save.c
+ ${CMAKE_CURRENT_LIST_DIR}/src/tx_thread_interrupt_control.c
+ ${CMAKE_CURRENT_LIST_DIR}/src/tx_thread_schedule.c
+ ${CMAKE_CURRENT_LIST_DIR}/src/tx_thread_smp_core_get.c
+ ${CMAKE_CURRENT_LIST_DIR}/src/tx_thread_smp_core_preempt.c
+ ${CMAKE_CURRENT_LIST_DIR}/src/tx_thread_smp_current_state_get.c
+ ${CMAKE_CURRENT_LIST_DIR}/src/tx_thread_smp_current_thread_get.c
+ ${CMAKE_CURRENT_LIST_DIR}/src/tx_thread_smp_initialize_wait.c
+ ${CMAKE_CURRENT_LIST_DIR}/src/tx_thread_smp_low_level_initialize.c
+ ${CMAKE_CURRENT_LIST_DIR}/src/tx_thread_smp_protect.c
+ ${CMAKE_CURRENT_LIST_DIR}/src/tx_thread_smp_time_get.c
+ ${CMAKE_CURRENT_LIST_DIR}/src/tx_thread_smp_unprotect.c
+ ${CMAKE_CURRENT_LIST_DIR}/src/tx_thread_stack_build.c
+ ${CMAKE_CURRENT_LIST_DIR}/src/tx_thread_system_return.c
+ ${CMAKE_CURRENT_LIST_DIR}/src/tx_timer_interrupt.c
+ # {{END_TARGET_SOURCES}}
+)
+
+target_include_directories(${PROJECT_NAME}
+ SYSTEM
+ PUBLIC
+ ${CMAKE_CURRENT_LIST_DIR}/inc
+)
+
+# The demo program beside the port. Off by default so the ordinary build
+# produces just the library; -DTHREADX_SAMPLE=ON adds the sample_threadx target.
+option(THREADX_SAMPLE "Build the sample program for this port" OFF)
+if(THREADX_SAMPLE)
+ add_subdirectory(${CMAKE_CURRENT_LIST_DIR}/example_build)
+endif()
diff --git a/ports_smp/linux/gnu/example_build/CMakeLists.txt b/ports_smp/linux/gnu/example_build/CMakeLists.txt
new file mode 100644
index 00000000..90d4078a
--- /dev/null
+++ b/ports_smp/linux/gnu/example_build/CMakeLists.txt
@@ -0,0 +1,17 @@
+# Build the sample_threadx program that ports/linux/gnu/Makefile builds, so the
+# CMake build can produce a runnable demo rather than only the library.
+#
+# Guarded by THREADX_SAMPLE in the parent so the default build stays a pure
+# library build.
+
+add_executable(sample_threadx)
+
+target_sources(sample_threadx PRIVATE ${CMAKE_CURRENT_LIST_DIR}/sample_threadx.c)
+
+target_include_directories(sample_threadx
+ PRIVATE
+ ${CMAKE_CURRENT_LIST_DIR}/../inc
+ ${CMAKE_CURRENT_LIST_DIR}/../../../../${TX_COMMON_DIR}/inc
+)
+
+target_link_libraries(sample_threadx PRIVATE threadx)
diff --git a/ports_smp/linux/gnu/inc/tx_port.h b/ports_smp/linux/gnu/inc/tx_port.h
index bb1021dd..b7da882a 100644
--- a/ports_smp/linux/gnu/inc/tx_port.h
+++ b/ports_smp/linux/gnu/inc/tx_port.h
@@ -9,6 +9,8 @@
* SPDX-License-Identifier: MIT
**************************************************************************/
+// Portions of this file were generated with AI assistance.
+
/**************************************************************************/
/**************************************************************************/
@@ -373,13 +375,21 @@ void _tx_linux_debug_entry_insert(char *action, char *file, unsigned long lin
*/
-#ifndef TX_MISRA_ENABLE
+/* The clock below is read for every trace event in both builds. The MISRA form
+ of the in-line insert takes the time stamp as an argument rather than reading
+ it itself, so the macro has to be an expression; that is why it carries no
+ trailing semicolon. */
+
#ifndef TX_TRACE_TIME_SOURCE
#define TX_TRACE_TIME_SOURCE ((ULONG) (_tx_linux_time_stamp.tv_nsec))
#endif
-#else
+
+/* Declared here rather than used: this port supplies its own time stamp above,
+ but the generic definition in common_smp/src/tx_misra.c is compiled for this
+ port and needs a declaration in scope. */
+
+#ifdef TX_MISRA_ENABLE
ULONG _tx_misra_time_stamp_get(VOID);
-#define TX_TRACE_TIME_SOURCE _tx_misra_time_stamp_get()
#endif
#ifndef TX_TRACE_TIME_MASK
@@ -503,6 +513,16 @@ typedef struct
} TX_LINUX_MUTEX;
+/* Define how long a thread waits on the Linux mutex before retrying. A thread
+ parked on the mutex can be suspended by the port's signal handler and so never
+ act on the wake-up the next release sends it, which leaves the wake-up lost
+ and every other waiter parked on a mutex that is free. */
+
+#ifndef TX_LINUX_MUTEX_RETRY_NSEC
+#define TX_LINUX_MUTEX_RETRY_NSEC 1000000
+#endif
+
+
/* Define Linux-specific critical section APIs. */
void _tx_linux_mutex_obtain(TX_LINUX_MUTEX *mutex);
@@ -622,7 +642,7 @@ void _tx_thread_smp_debug_entry_insert(ULONG id, ULONG su
#ifdef TX_THREAD_INIT
CHAR _tx_version_id[] =
- "(c) 2024 Microsoft Corp. (c) 2026-present Eclipse ThreadX contributors. * ThreadX SMP/Linux/gcc Version 6.5.1.202602a *";
+ "(c) 2024 Microsoft Corp. (c) 2026-present Eclipse ThreadX contributors. * ThreadX SMP/Linux/gcc Version 6.5.2.202603 *";
#else
extern CHAR _tx_version_id[];
#endif
diff --git a/ports_smp/linux/gnu/src/tx_thread_schedule.c b/ports_smp/linux/gnu/src/tx_thread_schedule.c
index 0c3e8e32..0b6eba25 100644
--- a/ports_smp/linux/gnu/src/tx_thread_schedule.c
+++ b/ports_smp/linux/gnu/src/tx_thread_schedule.c
@@ -292,6 +292,8 @@ void _tx_linux_mutex_obtain(TX_LINUX_MUTEX *mutex)
TX_THREAD *thread_ptr;
pthread_t current_thread_id;
UINT i;
+INT linux_status;
+struct timespec ts;
/* Pickup the current thread ID. */
current_thread_id = pthread_self();
@@ -343,8 +345,43 @@ UINT i;
thread_ptr -> tx_thread_linux_mutex_access = TX_TRUE;
}
- /* Get the Linux mutex. */
- pthread_mutex_lock(&mutex -> tx_linux_mutex);
+ /* Get the Linux mutex. The wait is timed and retried rather than left
+ to pthread_mutex_lock, because a thread can be signalled into the
+ port's suspend handler while it is parked on this mutex. That handler
+ does not return until the thread is resumed, so the wake-up the next
+ release sends is delivered to a thread that never retries and is lost.
+ Any other thread parked on the mutex then waits on a mutex that is
+ free, which on this port deadlocks the whole process: the thread that
+ can resume the suspended one is the scheduler, and the scheduler takes
+ this mutex on every pass. Retrying on a timeout costs nothing when
+ the mutex is handed over normally, and turns that lost wake-up into a
+ delay of at most the retry period. */
+ do
+ {
+
+ /* Set the deadline for this attempt. */
+ clock_gettime(CLOCK_REALTIME, &ts);
+ ts.tv_nsec = ts.tv_nsec + TX_LINUX_MUTEX_RETRY_NSEC;
+ if (ts.tv_nsec >= 1000000000)
+ {
+
+ ts.tv_nsec = ts.tv_nsec - 1000000000;
+ ts.tv_sec++;
+ }
+
+ linux_status = pthread_mutex_timedlock(&mutex -> tx_linux_mutex, &ts);
+
+ /* Anything but the deadline expiring is a real failure to obtain the
+ mutex, so stop retrying and record it. */
+ if ((linux_status != 0) && (linux_status != ETIMEDOUT))
+ {
+
+ /* Increment the system error counter. */
+ _tx_linux_system_error++;
+ break;
+ }
+
+ } while (linux_status != 0);
/* At this point we have the mutex. */
diff --git a/ports_smp/linux/gnu/src/tx_thread_smp_unprotect.c b/ports_smp/linux/gnu/src/tx_thread_smp_unprotect.c
index 7428666f..2e0e7f1e 100644
--- a/ports_smp/linux/gnu/src/tx_thread_smp_unprotect.c
+++ b/ports_smp/linux/gnu/src/tx_thread_smp_unprotect.c
@@ -9,6 +9,8 @@
* SPDX-License-Identifier: MIT
**************************************************************************/
+// Portions of this file were generated with AI assistance.
+
/**************************************************************************/
/**************************************************************************/
@@ -124,11 +126,18 @@ pthread_t current_thread_id;
_tx_linux_debug_entry_insert("UNPROTECT-nested", __FILE__, __LINE__);
}
- /* Only release the critical section. */
- _tx_linux_mutex_release(&_tx_linux_mutex);
}
- /* Release the critical section. */
+ /* Release the critical section taken by the matching _tx_thread_smp_protect.
+ The protection and the critical section are separate counts, and this
+ release is owed whether or not the protection still names this core: the
+ protection can be cleared by another core while this one holds the
+ critical section it took. The critical section is only handed back to
+ Linux when its nesting count reaches zero, so a release skipped here is
+ never made up and the mutex stays locked for the life of the process. */
+ _tx_linux_mutex_release(&_tx_linux_mutex);
+
+ /* Release the critical section taken on entry. */
_tx_linux_mutex_release(&_tx_linux_mutex);
}
diff --git a/ports_smp/linux/gnu/src/tx_thread_stack_build.c b/ports_smp/linux/gnu/src/tx_thread_stack_build.c
index 1b491a3a..65b8e25c 100644
--- a/ports_smp/linux/gnu/src/tx_thread_stack_build.c
+++ b/ports_smp/linux/gnu/src/tx_thread_stack_build.c
@@ -9,6 +9,8 @@
* SPDX-License-Identifier: MIT
**************************************************************************/
+// Portions of this file were generated with AI assistance.
+
/**************************************************************************/
/**************************************************************************/
@@ -80,6 +82,7 @@ void *_tx_linux_thread_entry(void *ptr);
/**************************************************************************/
VOID _tx_thread_stack_build(TX_THREAD *thread_ptr, VOID (*function_ptr)(VOID))
{
+ALIGN_TYPE fake_stack_ptr;
struct sched_param sp;
pthread_attr_t attrs;
@@ -120,8 +123,13 @@ pthread_attr_t attrs;
tx_interrupt_control nesting. */
thread_ptr -> tx_thread_linux_mutex_access = TX_FALSE;
- /* Setup a fake thread stack pointer. */
- thread_ptr -> tx_thread_stack_ptr = (VOID *) (((CHAR *) thread_ptr -> tx_thread_stack_end) - 8);
+ /* Setup a fake thread stack pointer. The stack end points at the last byte of the
+ thread's stack area and is therefore not necessarily aligned, so round the result
+ down to a ULONG boundary. This pointer is dereferenced as a ULONG below and is
+ also the starting value of the stack checking logic's highest used pointer. */
+ fake_stack_ptr = (ALIGN_TYPE) ((VOID *) (((CHAR *) thread_ptr -> tx_thread_stack_end) - 8));
+ fake_stack_ptr = fake_stack_ptr & (~((ALIGN_TYPE) (sizeof(ULONG) - 1)));
+ thread_ptr -> tx_thread_stack_ptr = (VOID *) ((ALIGN_TYPE) fake_stack_ptr);
/* Clear the first word of the stack. */
*(((ULONG *) thread_ptr -> tx_thread_stack_ptr) - 1) = 0;
diff --git a/ports_smp/mips32_interaptiv_smp/gnu/CMakeLists.txt b/ports_smp/mips32_interaptiv_smp/gnu/CMakeLists.txt
new file mode 100644
index 00000000..c54890aa
--- /dev/null
+++ b/ports_smp/mips32_interaptiv_smp/gnu/CMakeLists.txt
@@ -0,0 +1,34 @@
+# Copyright (c) 2026 Eclipse ThreadX contributors
+# SPDX-License-Identifier: MIT
+# Portions of this file were generated with AI assistance.
+#
+# ThreadX port sources for mips32_interaptiv_smp, GNU tools.
+
+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_interrupt_control.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_smp/mips32_interaptiv_smp/gnu/inc/tx_port.h b/ports_smp/mips32_interaptiv_smp/gnu/inc/tx_port.h
index 87ee3fcc..6e15542c 100644
--- a/ports_smp/mips32_interaptiv_smp/gnu/inc/tx_port.h
+++ b/ports_smp/mips32_interaptiv_smp/gnu/inc/tx_port.h
@@ -419,7 +419,7 @@ THREAD_SMP_DECLARE ULONG _tx_thread_smp_initial_fpu_control_register;
#ifdef TX_THREAD_INIT
CHAR _tx_version_id[] =
- "(c) 2024 Microsoft Corp. (c) 2026-present Eclipse ThreadX contributors. * ThreadX SMP MIPS32_interAptiv/GNU Version 6.5.1.202602a *";
+ "(c) 2024 Microsoft Corp. (c) 2026-present Eclipse ThreadX contributors. * ThreadX SMP MIPS32_interAptiv/GNU Version 6.5.2.202603 *";
#else
extern CHAR _tx_version_id[];
#endif
diff --git a/ports_smp/mips32_interaptiv_smp/green/inc/tx_port.h b/ports_smp/mips32_interaptiv_smp/green/inc/tx_port.h
index 06d0142e..20b1d56b 100644
--- a/ports_smp/mips32_interaptiv_smp/green/inc/tx_port.h
+++ b/ports_smp/mips32_interaptiv_smp/green/inc/tx_port.h
@@ -509,7 +509,7 @@ THREAD_SMP_DECLARE ULONG _tx_thread_smp_initial_fpu_control_register;
#ifdef TX_THREAD_INIT
CHAR _tx_version_id[] =
- "(c) 2024 Microsoft Corp. (c) 2026-present Eclipse ThreadX contributors. * ThreadX SMP MIPS32_interAptiv/Green Hills Version 6.5.1.202602a *";
+ "(c) 2024 Microsoft Corp. (c) 2026-present Eclipse ThreadX contributors. * ThreadX SMP MIPS32_interAptiv/Green Hills Version 6.5.2.202603 *";
#else
extern CHAR _tx_version_id[];
#endif
diff --git a/ports_smp/win64/vs_2022/CMakeLists.txt b/ports_smp/win64/vs_2022/CMakeLists.txt
index 982f9684..447a0026 100644
--- a/ports_smp/win64/vs_2022/CMakeLists.txt
+++ b/ports_smp/win64/vs_2022/CMakeLists.txt
@@ -23,6 +23,7 @@ target_sources(${PROJECT_NAME}
)
target_include_directories(${PROJECT_NAME}
+ SYSTEM
PUBLIC
${CMAKE_CURRENT_LIST_DIR}/inc
)
diff --git a/ports_smp/win64/vs_2022/inc/tx_port.h b/ports_smp/win64/vs_2022/inc/tx_port.h
index 15225230..949c812e 100644
--- a/ports_smp/win64/vs_2022/inc/tx_port.h
+++ b/ports_smp/win64/vs_2022/inc/tx_port.h
@@ -441,7 +441,7 @@ UINT _tx_thread_interrupt_control(UINT new_posture);
#ifdef TX_THREAD_INIT
CHAR _tx_version_id[] =
- "(c) 2026 Eclipse ThreadX contributors. * ThreadX SMP/Win64/MSVC Version 6.5.1.202602a *";
+ "(c) 2026 Eclipse ThreadX contributors. * ThreadX SMP/Win64/MSVC Version 6.5.2.202603 *";
#else
extern CHAR _tx_version_id[];
#endif
diff --git a/ports_smp/win64/vs_2022/src/tx_initialize_low_level.c b/ports_smp/win64/vs_2022/src/tx_initialize_low_level.c
index f517fd6b..9752ec3d 100644
--- a/ports_smp/win64/vs_2022/src/tx_initialize_low_level.c
+++ b/ports_smp/win64/vs_2022/src/tx_initialize_low_level.c
@@ -13,8 +13,7 @@
* SPDX-License-Identifier: MIT and CC0-1.0
**************************************************************************/
-// Some portions generated by Codex (gpt 5.5).
-// Some portions generated by GitHub Copilot (claude-sonnet-4.6).
+// Portions of this file were generated with AI assistance.
#define TX_SOURCE_CODE
#define TX_THREAD_SMP_SOURCE_CODE
diff --git a/ports_smp/win64/vs_2022/src/tx_thread_context_restore.c b/ports_smp/win64/vs_2022/src/tx_thread_context_restore.c
index d1b74c38..1a2cd182 100644
--- a/ports_smp/win64/vs_2022/src/tx_thread_context_restore.c
+++ b/ports_smp/win64/vs_2022/src/tx_thread_context_restore.c
@@ -13,8 +13,7 @@
* SPDX-License-Identifier: MIT and CC0-1.0
**************************************************************************/
-// Some portions generated by Codex (gpt 5.5).
-// Some portions generated by GitHub Copilot (claude-sonnet-4.6).
+// Portions of this file were generated with AI assistance.
#define TX_SOURCE_CODE
#define TX_THREAD_SMP_SOURCE_CODE
diff --git a/ports_smp/win64/vs_2022/src/tx_thread_context_save.c b/ports_smp/win64/vs_2022/src/tx_thread_context_save.c
index 89d6cd75..01a894c6 100644
--- a/ports_smp/win64/vs_2022/src/tx_thread_context_save.c
+++ b/ports_smp/win64/vs_2022/src/tx_thread_context_save.c
@@ -13,8 +13,7 @@
* SPDX-License-Identifier: MIT and CC0-1.0
**************************************************************************/
-// Some portions generated by Codex (gpt 5.4).
-// Some portions generated by GitHub Copilot (claude-sonnet-4.6).
+// Portions of this file were generated with AI assistance.
#define TX_SOURCE_CODE
#define TX_THREAD_SMP_SOURCE_CODE
diff --git a/ports_smp/win64/vs_2022/src/tx_thread_schedule.c b/ports_smp/win64/vs_2022/src/tx_thread_schedule.c
index f33eb7b0..b247ee4c 100644
--- a/ports_smp/win64/vs_2022/src/tx_thread_schedule.c
+++ b/ports_smp/win64/vs_2022/src/tx_thread_schedule.c
@@ -13,7 +13,7 @@
* SPDX-License-Identifier: MIT and CC0-1.0
**************************************************************************/
-// Some portions generated by Codex (gpt 5.5).
+// Portions of this file were generated with AI assistance.
#define TX_SOURCE_CODE
#define TX_THREAD_SMP_SOURCE_CODE
diff --git a/ports_smp/win64/vs_2022/src/tx_thread_smp_core_preempt.c b/ports_smp/win64/vs_2022/src/tx_thread_smp_core_preempt.c
index 2da24fda..4f0da534 100644
--- a/ports_smp/win64/vs_2022/src/tx_thread_smp_core_preempt.c
+++ b/ports_smp/win64/vs_2022/src/tx_thread_smp_core_preempt.c
@@ -13,7 +13,7 @@
* SPDX-License-Identifier: MIT and CC0-1.0
**************************************************************************/
-// Some portions generated by Codex (gpt 5.4).
+// Portions of this file were generated with AI assistance.
#define TX_SOURCE_CODE
#define TX_THREAD_SMP_SOURCE_CODE
diff --git a/ports_smp/win64/vs_2022/src/tx_thread_smp_current_state_get.c b/ports_smp/win64/vs_2022/src/tx_thread_smp_current_state_get.c
index bf1726df..ce937b19 100644
--- a/ports_smp/win64/vs_2022/src/tx_thread_smp_current_state_get.c
+++ b/ports_smp/win64/vs_2022/src/tx_thread_smp_current_state_get.c
@@ -13,7 +13,7 @@
* SPDX-License-Identifier: MIT and CC0-1.0
**************************************************************************/
-// Some portions generated by Codex (gpt 5.4).
+// Portions of this file were generated with AI assistance.
#define TX_SOURCE_CODE
#define TX_THREAD_SMP_SOURCE_CODE
diff --git a/ports_smp/win64/vs_2022/src/tx_thread_smp_current_thread_get.c b/ports_smp/win64/vs_2022/src/tx_thread_smp_current_thread_get.c
index ade6774f..1f93f8a9 100644
--- a/ports_smp/win64/vs_2022/src/tx_thread_smp_current_thread_get.c
+++ b/ports_smp/win64/vs_2022/src/tx_thread_smp_current_thread_get.c
@@ -13,7 +13,7 @@
* SPDX-License-Identifier: MIT and CC0-1.0
**************************************************************************/
-// Some portions generated by Codex (gpt 5.4).
+// Portions of this file were generated with AI assistance.
#define TX_SOURCE_CODE
#define TX_THREAD_SMP_SOURCE_CODE
diff --git a/ports_smp/win64/vs_2022/src/tx_thread_smp_protect.c b/ports_smp/win64/vs_2022/src/tx_thread_smp_protect.c
index e59caffc..954b9e3c 100644
--- a/ports_smp/win64/vs_2022/src/tx_thread_smp_protect.c
+++ b/ports_smp/win64/vs_2022/src/tx_thread_smp_protect.c
@@ -13,7 +13,7 @@
* SPDX-License-Identifier: MIT and CC0-1.0
**************************************************************************/
-// Some portions generated by Codex (gpt 5.5).
+// Portions of this file were generated with AI assistance.
#define TX_SOURCE_CODE
#define TX_THREAD_SMP_SOURCE_CODE
diff --git a/ports_smp/win64/vs_2022/src/tx_thread_smp_unprotect.c b/ports_smp/win64/vs_2022/src/tx_thread_smp_unprotect.c
index b845767d..ac553d66 100644
--- a/ports_smp/win64/vs_2022/src/tx_thread_smp_unprotect.c
+++ b/ports_smp/win64/vs_2022/src/tx_thread_smp_unprotect.c
@@ -13,7 +13,7 @@
* SPDX-License-Identifier: MIT and CC0-1.0
**************************************************************************/
-// Some portions generated by Codex (gpt 5.4).
+// Portions of this file were generated with AI assistance.
#define TX_SOURCE_CODE
#define TX_THREAD_SMP_SOURCE_CODE
diff --git a/ports_smp/win64/vs_2022/src/tx_thread_stack_build.c b/ports_smp/win64/vs_2022/src/tx_thread_stack_build.c
index 0531fb3b..60478e7b 100644
--- a/ports_smp/win64/vs_2022/src/tx_thread_stack_build.c
+++ b/ports_smp/win64/vs_2022/src/tx_thread_stack_build.c
@@ -13,7 +13,7 @@
* SPDX-License-Identifier: MIT and CC0-1.0
**************************************************************************/
-// Some portions generated by Codex (gpt 5.5).
+// Portions of this file were generated with AI assistance.
#define TX_SOURCE_CODE
#define TX_THREAD_SMP_SOURCE_CODE
diff --git a/ports_smp/win64/vs_2022/src/tx_thread_system_return.c b/ports_smp/win64/vs_2022/src/tx_thread_system_return.c
index 8207f345..b7690402 100644
--- a/ports_smp/win64/vs_2022/src/tx_thread_system_return.c
+++ b/ports_smp/win64/vs_2022/src/tx_thread_system_return.c
@@ -13,7 +13,7 @@
* SPDX-License-Identifier: MIT and CC0-1.0
**************************************************************************/
-// Some portions generated by Codex (gpt 5.5).
+// Portions of this file were generated with AI assistance.
#define TX_SOURCE_CODE
#define TX_THREAD_SMP_SOURCE_CODE