diff options
Diffstat (limited to 'ports_arch')
61 files changed, 1074 insertions, 489 deletions
diff --git a/ports_arch/ARMv7-A/threadx/common/inc/tx_port.h b/ports_arch/ARMv7-A/threadx/common/inc/tx_port.h index 15d6c3c5..798dc457 100644 --- a/ports_arch/ARMv7-A/threadx/common/inc/tx_port.h +++ b/ports_arch/ARMv7-A/threadx/common/inc/tx_port.h @@ -307,7 +307,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-A Version 6.5.1.202602a *"; + "(c) 2024 Microsoft Corp. (c) 2026-present Eclipse ThreadX contributors. * ThreadX ARMv7-A Version 6.5.2.202603 *"; #else extern CHAR _tx_version_id[]; #endif diff --git a/ports_arch/ARMv7-A/threadx/common/src/tx_thread_system_return.S b/ports_arch/ARMv7-A/threadx/common/src/tx_thread_system_return.S index 1a17446b..7671bba2 100644 --- a/ports_arch/ARMv7-A/threadx/common/src/tx_thread_system_return.S +++ b/ports_arch/ARMv7-A/threadx/common/src/tx_thread_system_return.S @@ -9,6 +9,7 @@ * SPDX-License-Identifier: MIT **************************************************************************/ +// Portions of this file were generated with AI assistance. /**************************************************************************/ /**************************************************************************/ @@ -121,7 +122,9 @@ _tx_skip_solicited_vfp_save: LDR r2, =_tx_timer_time_slice // Pickup address of time slice LDR r1, [r2] // Pickup current time slice - /* Save current stack and switch to system stack. */ + /* Save the current stack pointer in the thread control block. The + scheduler runs on the banked SVC mode stack that the startup code + set up, so there is no stack switch to perform. */ STR sp, [r0, #8] // Save thread stack pointer diff --git a/ports_arch/ARMv7-A/threadx/ports/ac6/example_build/sample_threadx/sample_threadx.launch b/ports_arch/ARMv7-A/threadx/ports/ac6/example_build/sample_threadx/sample_threadx.launch index 0bc5b11b..df957414 100644 --- a/ports_arch/ARMv7-A/threadx/ports/ac6/example_build/sample_threadx/sample_threadx.launch +++ b/ports_arch/ARMv7-A/threadx/ports/ac6/example_build/sample_threadx/sample_threadx.launch @@ -124,7 +124,7 @@ <booleanAttribute key="VFS_ENABLED" value="true"/> <stringAttribute key="VFS_LOCAL_DIR" value="${workspace_loc}"/> <stringAttribute key="VFS_REMOTE_MOUNT" value="/writeable"/> - <stringAttribute key="breakpoints" value="<?xml version="1.0" encoding="UTF-8"?> <breakpoints order="ALPHA"> 	<breakpoint ignorecount="0" threadenabled="no" core_list="" continue="no" verboseBreakpoints="yes" kind="SOURCEPOSITION"> 		<master_location index="0" enabled="true" version="2" hostFile="C:\Users\nisohack\Documents\work\x-ware_libs\threadx_github\ports\cortex_a7\ac6\example_build\sample_threadx\tx_initialize_low_level.S" line="215"/> 		<location index="0" enabled="true" version="2" address="S:0x80000314" debugFile="C:/Users/nisohack/Documents/work/x-ware_libs/threadx_github/ports/cortex_a7/ac6/example_build/sample_threadx/tx_initialize_low_level.S" hostFile="C:\Users\nisohack\Documents\work\x-ware_libs\threadx_github\ports\cortex_a7\ac6\example_build\sample_threadx\tx_initialize_low_level.S" line="238"/> 	</breakpoint> </breakpoints> "/> + <stringAttribute key="breakpoints" value="<?xml version="1.0" encoding="UTF-8"?> <breakpoints order="ALPHA"> </breakpoints> "/> <listAttribute key="com.arm.debug.views.common.AddressTracker.debugger.view.DisassemblyView.addresses"> <listEntry value="<Next Instruction>"/> </listAttribute> diff --git a/ports_arch/ARMv7-A/threadx/ports/gnu/CMakeLists.txt b/ports_arch/ARMv7-A/threadx/ports/gnu/CMakeLists.txt new file mode 100644 index 00000000..fc215876 --- /dev/null +++ b/ports_arch/ARMv7-A/threadx/ports/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 the ARMv7-A cores, GNU tools. +# Copied into every ARMv7-A gnu port by update.sh, so edit it here. + +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_fiq_context_restore.S + ${CMAKE_CURRENT_LIST_DIR}/src/tx_thread_fiq_context_save.S + ${CMAKE_CURRENT_LIST_DIR}/src/tx_thread_fiq_nesting_end.S + ${CMAKE_CURRENT_LIST_DIR}/src/tx_thread_fiq_nesting_start.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_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_arch/ARMv7-A/threadx/ports/iar/example_build/tx.ewp b/ports_arch/ARMv7-A/threadx/ports/iar/example_build/tx.ewp index ef9fb474..72f03a7a 100644 --- a/ports_arch/ARMv7-A/threadx/ports/iar/example_build/tx.ewp +++ b/ports_arch/ARMv7-A/threadx/ports/iar/example_build/tx.ewp @@ -1047,7 +1047,7 @@ </option> <option> <name>IarchiveOutput</name> - <state>C:\release\threadx\Debug\Exe\tx.a</state> + <state>###Unitialized###</state> </option> </data> </settings> diff --git a/ports_arch/ARMv7-A/update.sh b/ports_arch/ARMv7-A/update.sh new file mode 100755 index 00000000..6272a59a --- /dev/null +++ b/ports_arch/ARMv7-A/update.sh @@ -0,0 +1,164 @@ +#!/bin/bash +############################################################################## +# Copyright (C) 2026 Eclipse ThreadX contributors +# +# This program and the accompanying materials are made available under the +# terms of the MIT License which is available at +# https://opensource.org/licenses/MIT. +# +# AI Disclosure: This file was largely AI-generated by Claude Code (Opus 5). +# The AI-generated portions may be considered public domain (CC0-1.0) +# and not subject to the project's licence. The human contributor has +# reviewed and verified that the code is correct. +# +# SPDX-License-Identifier: MIT and CC0-1.0 +############################################################################## + +# Update the ARMv7-A ports from the generic ARMv7-A port, generating ports and +# examples from the common files. This is a port of update.ps1 beside it, which +# needs PowerShell and so could only be run on Windows. The two are kept +# equivalent: same cores, same compilers, same copy sets and the same patches. +# +# To update the ThreadX ports for the source tree: +# ./update.sh --port-sets tx --copy-common-files --copy-port-files \ +# --copy-example --patch-files +# +# To update the ThreadX ports for the test tree: +# ./update.sh --port-sets tx --copy-common-files --copy-port-files \ +# --copy-example --copy-validation-test --copy-regression-test \ +# --patch-files +# +# --copy-example, --copy-validation-test and --copy-regression-test are +# accepted and ignored, exactly as in update.ps1, where they are declared as +# parameters but never consulted. They are kept so that both scripts take the +# same command line. + +set -eu + +cd "$(dirname "$(realpath "$0")")" + +cores="cortex_a5 cortex_a7 cortex_a8 cortex_a9 cortex_a12 cortex_a15 cortex_a17" +compilers="ac6 gnu" + +port_sets="" +copy_common_files=0 +copy_port_files=0 +patch_files=0 + +usage() { + sed -n '22,35p' "$0" + exit "${1:-1}" +} + +while [ "$#" -gt 0 ]; do + case "$1" in + --port-sets) + [ "$#" -ge 2 ] || { echo "Error: --port-sets needs a value" >&2; exit 1; } + port_sets="$(printf '%s' "$2" | tr ',' ' ')" + shift 2 + ;; + --copy-common-files) copy_common_files=1; shift ;; + --copy-port-files) copy_port_files=1; shift ;; + --patch-files) patch_files=1; shift ;; + # Accepted and ignored, as in update.ps1. + --copy-example|--copy-validation-test|--copy-regression-test) shift ;; + -h|--help) usage 0 ;; + *) echo "Error: unknown option '$1'" >&2; usage ;; + esac +done + +if [ -z "${port_sets}" ]; then + echo "Error: --port-sets is required" >&2 + usage +fi + +for port_set in ${port_sets}; do + case "${port_set}" in + tx|tx_smp|txm|txm_smp) ;; + *) echo "Error: invalid port set '${port_set}'" >&2; exit 1 ;; + esac +done + +echo "Update the ARMv7-A ports" + +# Copy the contents of a directory over a destination, creating what is missing +# and overwriting what is not. This mirrors Copy-Item -Recurse -Force, which +# merges into the destination rather than replacing it. +copy_files() { + source_dir="$1" + destination_directory="$2" + + if [ -d "${source_dir}" ]; then + cp -Rf "${source_dir}/." "${destination_directory}/" + fi +} + +# Replace every occurrence of a literal string in a file, leaving the file +# alone when it does not exist. Only the files named in the patch list below +# are ever touched. +patch_file() { + path="$1" + original="$2" + substitute="$3" + + [ -f "${path}" ] || return 0 + + original_escaped="$(printf '%s' "${original}" | sed -e 's/[][\.*^$/&]/\\&/g')" + substitute_escaped="$(printf '%s' "${substitute}" | sed -e 's/[\/&]/\\&/g')" + sed -i "s/${original_escaped}/${substitute_escaped}/g" "${path}" +} + +for port_set in ${port_sets}; do + for core in ${cores}; do + case "${port_set}" in + tx) core_directory="../../ports/${core}" ;; + tx_smp) core_directory="../../ports_smp/${core}_smp" ;; + txm) core_directory="../../ports_module/${core}" ;; + txm_smp) core_directory="../../ports_module_smp/${core}_smp" ;; + esac + + core_short="${core#cortex_}" + core_short_lower="$(printf '%s' "${core_short}" | tr '[:upper:]' '[:lower:]')" + core_short_upper="$(printf '%s' "${core_short}" | tr '[:lower:]' '[:upper:]')" + + for compiler in ${compilers}; do + destination_directory="${core_directory}/${compiler}" + mkdir -p "${destination_directory}" + + if [ "${copy_common_files}" -eq 1 ]; then + copy_files "threadx/common" "${destination_directory}" + fi + + if [ "${copy_port_files}" -eq 1 ]; then + copy_files "threadx/ports/${compiler}" "${destination_directory}" + fi + + if [ "${port_set}" = "tx_smp" ]; then + if [ "${copy_common_files}" -eq 1 ]; then + copy_files "threadx_smp/common" "${destination_directory}" + fi + if [ "${copy_port_files}" -eq 1 ]; then + copy_files "threadx_smp/ports/${compiler}" "${destination_directory}" + fi + fi + + if [ "${patch_files}" -eq 1 ]; then + sample_cproject="${destination_directory}/example_build/sample_threadx/.cproject" + patch_file "${sample_cproject}" 'value="cortex-a7"' "value=\"cortex-${core_short_lower}\"" + patch_file "${sample_cproject}" 'Cortex-A7.NoFPU' "Cortex-${core_short_upper}.NoFPU" + + tx_cproject="${destination_directory}/example_build/tx/.cproject" + patch_file "${tx_cproject}" 'value="cortex-a7"' "value=\"cortex-${core_short_lower}\"" + patch_file "${tx_cproject}" 'Cortex-A7.NoFPU' "Cortex-${core_short_upper}.NoFPU" + + launch="${destination_directory}/example_build/sample_threadx/sample_threadx.launch" + patch_file "${launch}" 'Debug Cortex-A7' "Debug Cortex-${core_short_upper}" + patch_file "${launch}" 'VE_Cortex_A7x1' "VE_Cortex_${core_short_upper}x1" + patch_file "${launch}" 've_cortex_a7x1' "ve_cortex_${core_short_lower}x1" + patch_file "${launch}" 'FVP_VE_Cortex-A7x1' "FVP_VE_Cortex-${core_short_upper}x1" + fi + done + done +done + +echo "Done." diff --git a/ports_arch/ARMv7-M/threadx/ac5/example_build/tx_initialize_low_level.s b/ports_arch/ARMv7-M/threadx/ac5/example_build/tx_initialize_low_level.s index c51e67cf..5df0582e 100644 --- a/ports_arch/ARMv7-M/threadx/ac5/example_build/tx_initialize_low_level.s +++ b/ports_arch/ARMv7-M/threadx/ac5/example_build/tx_initialize_low_level.s @@ -8,6 +8,7 @@ * * SPDX-License-Identifier: MIT **************************************************************************/ +// Portions of this file were generated with AI assistance. /**************************************************************************/ @@ -20,7 +21,6 @@ /**************************************************************************/ /**************************************************************************/ - IMPORT _tx_thread_system_stack_ptr IMPORT _tx_initialize_unused_memory IMPORT _tx_thread_context_save IMPORT _tx_thread_context_restore @@ -151,20 +151,12 @@ _tx_initialize_low_level ADD r1, r1, #4 // Add 4 to get to next free word STR r1, [r0] // Setup first unused memory pointer - /* Setup Vector Table Offset Register. */ - MOV r0, #0xE000E000 // Build address of NVIC registers - LDR r1, =__tx_vectors // Pickup address of vector table - STR r1, [r0, #0xD08] // Set vector table address - - /* Set system stack pointer from vector value. */ - LDR r0, =_tx_thread_system_stack_ptr // Build address of system stack pointer - LDR r1, =__tx_vectors // Pickup address of vector table - LDR r1, [r1] // Pickup reset stack pointer - STR r1, [r0] // Save system stack pointer - #ifndef TX_NO_TIMER /* Configure SysTick. */ MOV r0, #0xE000E000 // Build address of NVIC registers + MOV r1, #0 // Build value for SysTick reset + STR r1, [r0, #0x10] // Reset SysTick Control + STR r1, [r0, #0x18] // Reset SysTick Counter Value LDR r1, =SYSTICK_CYCLES STR r1, [r0, #0x14] // Setup SysTick Reload Value MOV r1, #0x7 // Build SysTick Control Enable Value diff --git a/ports_arch/ARMv7-M/threadx/ac5/src/tx_thread_schedule.s b/ports_arch/ARMv7-M/threadx/ac5/src/tx_thread_schedule.s index 12da7d69..3e237f31 100644 --- a/ports_arch/ARMv7-M/threadx/ac5/src/tx_thread_schedule.s +++ b/ports_arch/ARMv7-M/threadx/ac5/src/tx_thread_schedule.s @@ -9,6 +9,8 @@ * SPDX-License-Identifier: MIT **************************************************************************/ +// Portions of this file were generated with AI assistance. + /**************************************************************************/ /**************************************************************************/ @@ -132,7 +134,7 @@ __tx_ts_handler BL _tx_execution_thread_exit // Call the thread exit function POP {r0, lr} // Recover LR #ifdef TX_PORT_USE_BASEPRI - MOV r0, 0 // Disable BASEPRI masking (enable interrupts) + MOV r0, #0 // Disable BASEPRI masking (enable interrupts) MSR BASEPRI, r0 #else CPSIE i // Enable interrupts @@ -260,9 +262,19 @@ __tx_ts_wait #endif #ifdef TX_ENABLE_WFI +#ifdef TX_PORT_USE_BASEPRI + CPSID i // Mask every interrupt with PRIMASK, which WFI ignores + MOV r1, #0 // Clear BASEPRI so that an interrupt masked by it + MSR BASEPRI, r1 // is still able to wake the processor +#endif DSB // Ensure no outstanding memory transactions WFI // Wait for interrupt ISB // Ensure pipeline is flushed +#ifdef TX_PORT_USE_BASEPRI + LDR r1, =TX_PORT_BASEPRI // Restore the BASEPRI mask + MSR BASEPRI, r1 + CPSIE i // Clear PRIMASK; a pending interrupt is taken here +#endif #endif #ifdef TX_LOW_POWER diff --git a/ports_arch/ARMv7-M/threadx/ac6/example_build/sample_threadx/tx_initialize_low_level.S b/ports_arch/ARMv7-M/threadx/ac6/example_build/sample_threadx/tx_initialize_low_level.S index af332d80..d14efe4d 100644 --- a/ports_arch/ARMv7-M/threadx/ac6/example_build/sample_threadx/tx_initialize_low_level.S +++ b/ports_arch/ARMv7-M/threadx/ac6/example_build/sample_threadx/tx_initialize_low_level.S @@ -8,6 +8,7 @@ * * SPDX-License-Identifier: MIT **************************************************************************/ +// Portions of this file were generated with AI assistance. /**************************************************************************/ @@ -20,7 +21,6 @@ /**************************************************************************/ /**************************************************************************/ - .global _tx_thread_system_stack_ptr .global _tx_initialize_unused_memory #ifndef TX_NO_TIMER .global _tx_timer_interrupt @@ -93,20 +93,12 @@ _tx_initialize_low_level: ADD r1, r1, #4 // STR r1, [r0] // Setup first unused memory pointer - /* Setup Vector Table Offset Register. */ - MOV r0, #0xE000E000 // Build address of NVIC registers - LDR r1, =vector_table // Pickup address of vector table - STR r1, [r0, #0xD08] // Set vector table address - - /* Set system stack pointer from vector value. */ - LDR r0, =_tx_thread_system_stack_ptr // Build address of system stack pointer - LDR r1, =vector_table // Pickup address of vector table - LDR r1, [r1] // Pickup reset stack pointer - STR r1, [r0] // Save system stack pointer - #ifndef TX_NO_TIMER /* Configure SysTick. */ MOV r0, #0xE000E000 // Build address of NVIC registers + MOV r1, #0 // Build value for SysTick reset + STR r1, [r0, #0x10] // Reset SysTick Control + STR r1, [r0, #0x18] // Reset SysTick Counter Value LDR r1, =SYSTICK_CYCLES STR r1, [r0, #0x14] // Setup SysTick Reload Value MOV r1, #0x7 // Build SysTick Control Enable Value diff --git a/ports_arch/ARMv7-M/threadx/ac6/src/tx_thread_schedule.S b/ports_arch/ARMv7-M/threadx/ac6/src/tx_thread_schedule.S index 1aade9e5..5f600c7d 100644 --- a/ports_arch/ARMv7-M/threadx/ac6/src/tx_thread_schedule.S +++ b/ports_arch/ARMv7-M/threadx/ac6/src/tx_thread_schedule.S @@ -8,6 +8,7 @@ * * SPDX-License-Identifier: MIT **************************************************************************/ +// Portions of this file were generated with AI assistance. /**************************************************************************/ @@ -139,7 +140,7 @@ __tx_ts_handler: BL _tx_execution_thread_exit // Call the thread exit function POP {r0, lr} // Recover LR #ifdef TX_PORT_USE_BASEPRI - MOV r0, 0 // Disable BASEPRI masking (enable interrupts) + MOV r0, #0 // Disable BASEPRI masking (enable interrupts) MSR BASEPRI, r0 #else CPSIE i // Enable interrupts @@ -267,9 +268,19 @@ __tx_ts_wait: #endif #ifdef TX_ENABLE_WFI +#ifdef TX_PORT_USE_BASEPRI + CPSID i // Mask every interrupt with PRIMASK, which WFI ignores + MOV r1, #0 // Clear BASEPRI so that an interrupt masked by it + MSR BASEPRI, r1 // is still able to wake the processor +#endif DSB // Ensure no outstanding memory transactions WFI // Wait for interrupt ISB // Ensure pipeline is flushed +#ifdef TX_PORT_USE_BASEPRI + LDR r1, =TX_PORT_BASEPRI // Restore the BASEPRI mask + MSR BASEPRI, r1 + CPSIE i // Clear PRIMASK; a pending interrupt is taken here +#endif #endif #ifdef TX_LOW_POWER diff --git a/ports_arch/ARMv7-M/threadx/ac6/src/tx_thread_system_return.S b/ports_arch/ARMv7-M/threadx/ac6/src/tx_thread_system_return.S index 75d51813..efa4e03f 100644 --- a/ports_arch/ARMv7-M/threadx/ac6/src/tx_thread_system_return.S +++ b/ports_arch/ARMv7-M/threadx/ac6/src/tx_thread_system_return.S @@ -9,6 +9,8 @@ * SPDX-License-Identifier: MIT **************************************************************************/ +// Portions of this file were generated with AI assistance. + /**************************************************************************/ /**************************************************************************/ @@ -73,6 +75,8 @@ _tx_thread_system_return: MOV r0, #0x10000000 // Load PENDSVSET bit MOV r1, #0xE000E000 // Load NVIC base STR r0, [r1, #0xD04] // Set PENDSVBIT in ICSR + DSB #0xF // Ensure memory access is complete + ISB #0xF // Flush pipeline MRS r0, IPSR // Pickup IPSR CMP r0, #0 // Is it a thread returning? BNE _isr_context // If ISR, skip interrupt enable @@ -81,10 +85,12 @@ _tx_thread_system_return: MOV r0, #0 MSR BASEPRI, r0 // Enable interrupts MSR BASEPRI, r1 // Restore original interrupt posture + ISB #0xF // Flush pipeline #else MRS r1, PRIMASK // Thread context returning, pickup PRIMASK CPSIE i // Enable interrupts MSR PRIMASK, r1 // Restore original interrupt posture + ISB #0xF // Flush pipeline #endif _isr_context: BX lr // Return to caller diff --git a/ports_arch/ARMv7-M/threadx/ghs/example_build/tx_initialize_low_level.arm b/ports_arch/ARMv7-M/threadx/ghs/example_build/tx_initialize_low_level.arm index 57c964b3..7c2b80ab 100644 --- a/ports_arch/ARMv7-M/threadx/ghs/example_build/tx_initialize_low_level.arm +++ b/ports_arch/ARMv7-M/threadx/ghs/example_build/tx_initialize_low_level.arm @@ -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 @@ -7,6 +8,7 @@ * * SPDX-License-Identifier: MIT **************************************************************************/ +; Portions of this file were generated with AI assistance. /**************************************************************************/ @@ -75,13 +77,6 @@ _tx_initialize_low_level: CPSID i ; Disable interrupts - /* Save the system stack pointer. */ - /* _tx_thread_system_stack_ptr = (VOID_PTR) (sp); */ - - LDR r1,=_tx_thread_system_stack_ptr ; Pickup address of system stack ptr - STR sp, [r1] ; Save system stack - - /* Save the first available memory address. */ /* _tx_initialize_unused_memory = (VOID_PTR) __ghsbegin_free_mem; */ @@ -98,15 +93,12 @@ _tx_initialize_low_level: STR r1, [r0] ; Enable the cycle count register - /* Setup Vector Table Offset Register. */ - - MOV r0, 0xE000E000 ; Build address of NVIC registers - LDR r1, =__vectors ; Pickup address of vector table - STR r1, [r0, 0xD08] ; Set vector table address - - /* Configure SysTick for 100Hz clock, or 16384 cycles if no reference. */ + MOV r0, 0xE000E000 ; Build address of NVIC registers + MOV r1, 0 ; Build value for SysTick reset + STR r1, [r0, 0x10] ; Reset SysTick Control + STR r1, [r0, 0x18] ; Reset SysTick Counter Value LDR r1, =SYSTICK_CYCLES STR r1, [r0, 0x14] ; Setup SysTick Reload Value MOV r1, 0x7 ; Build SysTick Control Enable Value diff --git a/ports_arch/ARMv7-M/threadx/ghs/inc/tx_port.h b/ports_arch/ARMv7-M/threadx/ghs/inc/tx_port.h index 41b32b43..b28ef5c5 100644 --- a/ports_arch/ARMv7-M/threadx/ghs/inc/tx_port.h +++ b/ports_arch/ARMv7-M/threadx/ghs/inc/tx_port.h @@ -387,7 +387,7 @@ void tx_thread_fpu_disable(void); #ifdef TX_THREAD_INIT CHAR _tx_version_id[] = - "(c) 2024 Microsoft Corp. (c) 2026-present Eclipse ThreadX contributors. * ThreadX ARMv7-M Version 6.5.1.202602a *"; + "(c) 2024 Microsoft Corp. (c) 2026-present Eclipse ThreadX contributors. * ThreadX ARMv7-M Version 6.5.2.202603 *"; #else #ifdef TX_MISRA_ENABLE extern CHAR _tx_version_id[100]; diff --git a/ports_arch/ARMv7-M/threadx/gnu/CMakeLists.txt b/ports_arch/ARMv7-M/threadx/gnu/CMakeLists.txt index ab9464d2..4abc1c06 100644 --- a/ports_arch/ARMv7-M/threadx/gnu/CMakeLists.txt +++ b/ports_arch/ARMv7-M/threadx/gnu/CMakeLists.txt @@ -13,6 +13,8 @@ target_sources(${PROJECT_NAME} PRIVATE # {{END_TARGET_SOURCES}} ) -target_include_directories(${PROJECT_NAME} PUBLIC +target_include_directories(${PROJECT_NAME} + SYSTEM + PUBLIC ${CMAKE_CURRENT_LIST_DIR}/inc ) diff --git a/ports_arch/ARMv7-M/threadx/gnu/example_build/tx_initialize_low_level.S b/ports_arch/ARMv7-M/threadx/gnu/example_build/tx_initialize_low_level.S index 8fce83db..a8bb445b 100644 --- a/ports_arch/ARMv7-M/threadx/gnu/example_build/tx_initialize_low_level.S +++ b/ports_arch/ARMv7-M/threadx/gnu/example_build/tx_initialize_low_level.S @@ -8,6 +8,7 @@ * * SPDX-License-Identifier: MIT **************************************************************************/ +// Portions of this file were generated with AI assistance. /**************************************************************************/ @@ -20,12 +21,10 @@ /**************************************************************************/ /**************************************************************************/ - .global _tx_thread_system_stack_ptr .global _tx_initialize_unused_memory .global __RAM_segment_used_end__ .global _tx_timer_interrupt .global __main - .global _vectors .global __tx_NMIHandler // NMI .global __tx_BadHandler // HardFault .global __tx_SVCallHandler // SVCall @@ -90,20 +89,12 @@ _tx_initialize_low_level: ADD r1, r1, #4 // STR r1, [r0] // Setup first unused memory pointer - /* Setup Vector Table Offset Register. */ - MOV r0, #0xE000E000 // Build address of NVIC registers - LDR r1, =_vectors // Pickup address of vector table - STR r1, [r0, #0xD08] // Set vector table address - - /* Set system stack pointer from vector value. */ - LDR r0, =_tx_thread_system_stack_ptr // Build address of system stack pointer - LDR r1, =_vectors // Pickup address of vector table - LDR r1, [r1] // Pickup reset stack pointer - STR r1, [r0] // Save system stack pointer - #ifndef TX_NO_TIMER /* Configure SysTick. */ MOV r0, #0xE000E000 // Build address of NVIC registers + MOV r1, #0 // Build value for SysTick reset + STR r1, [r0, #0x10] // Reset SysTick Control + STR r1, [r0, #0x18] // Reset SysTick Counter Value LDR r1, =SYSTICK_CYCLES STR r1, [r0, #0x14] // Setup SysTick Reload Value MOV r1, #0x7 // Build SysTick Control Enable Value diff --git a/ports_arch/ARMv7-M/threadx/gnu/src/tx_thread_schedule.S b/ports_arch/ARMv7-M/threadx/gnu/src/tx_thread_schedule.S index 65c5ad50..182eb81a 100644 --- a/ports_arch/ARMv7-M/threadx/gnu/src/tx_thread_schedule.S +++ b/ports_arch/ARMv7-M/threadx/gnu/src/tx_thread_schedule.S @@ -8,6 +8,7 @@ * * SPDX-License-Identifier: MIT **************************************************************************/ +// Portions of this file were generated with AI assistance. /**************************************************************************/ @@ -137,7 +138,7 @@ __tx_ts_handler: BL _tx_execution_thread_exit // Call the thread exit function POP {r0, lr} // Recover LR #ifdef TX_PORT_USE_BASEPRI - MOV r0, 0 // Disable BASEPRI masking (enable interrupts) + MOV r0, #0 // Disable BASEPRI masking (enable interrupts) MSR BASEPRI, r0 #else CPSIE i // Enable interrupts @@ -265,9 +266,19 @@ __tx_ts_wait: #endif #ifdef TX_ENABLE_WFI +#ifdef TX_PORT_USE_BASEPRI + CPSID i // Mask every interrupt with PRIMASK, which WFI ignores + MOV r1, #0 // Clear BASEPRI so that an interrupt masked by it + MSR BASEPRI, r1 // is still able to wake the processor +#endif DSB // Ensure no outstanding memory transactions WFI // Wait for interrupt ISB // Ensure pipeline is flushed +#ifdef TX_PORT_USE_BASEPRI + LDR r1, =TX_PORT_BASEPRI // Restore the BASEPRI mask + MSR BASEPRI, r1 + CPSIE i // Clear PRIMASK; a pending interrupt is taken here +#endif #endif #ifdef TX_LOW_POWER diff --git a/ports_arch/ARMv7-M/threadx/gnu/src/tx_thread_system_return.S b/ports_arch/ARMv7-M/threadx/gnu/src/tx_thread_system_return.S index 8b681747..ab050566 100644 --- a/ports_arch/ARMv7-M/threadx/gnu/src/tx_thread_system_return.S +++ b/ports_arch/ARMv7-M/threadx/gnu/src/tx_thread_system_return.S @@ -9,6 +9,8 @@ * SPDX-License-Identifier: MIT **************************************************************************/ +// Portions of this file were generated with AI assistance. + /**************************************************************************/ /**************************************************************************/ @@ -73,6 +75,8 @@ _tx_thread_system_return: MOV r0, #0x10000000 // Load PENDSVSET bit MOV r1, #0xE000E000 // Load NVIC base STR r0, [r1, #0xD04] // Set PENDSVBIT in ICSR + DSB #0xF // Ensure memory access is complete + ISB #0xF // Flush pipeline MRS r0, IPSR // Pickup IPSR CMP r0, #0 // Is it a thread returning? BNE _isr_context // If ISR, skip interrupt enable @@ -81,10 +85,12 @@ _tx_thread_system_return: MOV r0, #0 MSR BASEPRI, r0 // Enable interrupts MSR BASEPRI, r1 // Restore original interrupt posture + ISB #0xF // Flush pipeline #else MRS r1, PRIMASK // Thread context returning, pickup PRIMASK CPSIE i // Enable interrupts MSR PRIMASK, r1 // Restore original interrupt posture + ISB #0xF // Flush pipeline #endif _isr_context: BX lr // Return to caller diff --git a/ports_arch/ARMv7-M/threadx/iar/example_build/tx.ewp b/ports_arch/ARMv7-M/threadx/iar/example_build/tx.ewp index cccb9a9a..15b9ab10 100644 --- a/ports_arch/ARMv7-M/threadx/iar/example_build/tx.ewp +++ b/ports_arch/ARMv7-M/threadx/iar/example_build/tx.ewp @@ -1047,7 +1047,7 @@ </option> <option> <name>IarchiveOutput</name> - <state>C:\Users\sclarson\repos\tx_m\ports\armv7-m\iar\sample_cortex_m4\Debug\Exe\tx.a</state> + <state>###Unitialized###</state> </option> </data> </settings> diff --git a/ports_arch/ARMv7-M/threadx/iar/example_build/tx_initialize_low_level.s b/ports_arch/ARMv7-M/threadx/iar/example_build/tx_initialize_low_level.s index d2c2e07f..54aa4231 100644 --- a/ports_arch/ARMv7-M/threadx/iar/example_build/tx_initialize_low_level.s +++ b/ports_arch/ARMv7-M/threadx/iar/example_build/tx_initialize_low_level.s @@ -8,6 +8,7 @@ * * SPDX-License-Identifier: MIT **************************************************************************/ +// Portions of this file were generated with AI assistance. /**************************************************************************/ @@ -20,10 +21,8 @@ /**************************************************************************/ /**************************************************************************/ - EXTERN _tx_thread_system_stack_ptr EXTERN _tx_initialize_unused_memory EXTERN _tx_timer_interrupt - EXTERN __vector_table EXTERN _tx_execution_isr_enter EXTERN _tx_execution_isr_exit @@ -84,20 +83,12 @@ _tx_initialize_low_level: LDR r2, =_tx_initialize_unused_memory // Build address of unused memory pointer STR r0, [r2, #0] // Save first free memory address - /* Setup Vector Table Offset Register. */ - MOV r0, #0xE000E000 // Build address of NVIC registers - LDR r1, =__vector_table // Pickup address of vector table - STR r1, [r0, #0xD08] // Set vector table address - - /* Set system stack pointer from vector value. */ - LDR r0, =_tx_thread_system_stack_ptr // Build address of system stack pointer - LDR r1, =__vector_table // Pickup address of vector table - LDR r1, [r1] // Pickup reset stack pointer - STR r1, [r0] // Save system stack pointer - #ifndef TX_NO_TIMER /* Configure SysTick. */ MOV r0, #0xE000E000 // Build address of NVIC registers + MOV r1, #0 // Build value for SysTick reset + STR r1, [r0, #0x10] // Reset SysTick Control + STR r1, [r0, #0x18] // Reset SysTick Counter Value LDR r1, =SYSTICK_CYCLES STR r1, [r0, #0x14] // Setup SysTick Reload Value MOV r1, #0x7 // Build SysTick Control Enable Value diff --git a/ports_arch/ARMv7-M/threadx/iar/src/tx_iar.c b/ports_arch/ARMv7-M/threadx/iar/src/tx_iar.c index 238b485e..ab6c209c 100644 --- a/ports_arch/ARMv7-M/threadx/iar/src/tx_iar.c +++ b/ports_arch/ARMv7-M/threadx/iar/src/tx_iar.c @@ -9,6 +9,7 @@ * SPDX-License-Identifier: MIT **************************************************************************/ +// Portions of this file were generated with AI assistance. /**************************************************************************/ /**************************************************************************/ @@ -270,7 +271,7 @@ TX_MUTEX *mutex_ptr; mutex_ptr = &__tx_iar_file_lock_mutexes[__tx_iar_file_lock_next_free_mutex++]; /* Check for wrap-around on the next free mutex. */ - if (__tx_iar_file_lock_next_free_mutex >= _MAX_LOCK) + if (__tx_iar_file_lock_next_free_mutex >= _MAX_FLOCK) { /* Yes, set the free index back to 0. */ @@ -287,7 +288,7 @@ TX_MUTEX *mutex_ptr; } /* Determine if a free mutex was found. */ - if (i >= _MAX_LOCK) + if (i >= _MAX_FLOCK) { /* Error! No more free mutexes! */ @@ -678,7 +679,7 @@ TX_MUTEX *mutex_ptr; mutex_ptr = &__tx_iar_file_lock_mutexes[__tx_iar_file_lock_next_free_mutex++]; /* Check for wrap-around on the next free mutex. */ - if (__tx_iar_file_lock_next_free_mutex >= _MAX_LOCK) + if (__tx_iar_file_lock_next_free_mutex >= _MAX_FLOCK) { /* Yes, set the free index back to 0. */ @@ -695,7 +696,7 @@ TX_MUTEX *mutex_ptr; } /* Determine if a free mutex was found. */ - if (i >= _MAX_LOCK) + if (i >= _MAX_FLOCK) { /* Error! No more free mutexes! */ diff --git a/ports_arch/ARMv7-M/threadx/iar/src/tx_thread_schedule.s b/ports_arch/ARMv7-M/threadx/iar/src/tx_thread_schedule.s index d38774b8..f33e6277 100644 --- a/ports_arch/ARMv7-M/threadx/iar/src/tx_thread_schedule.s +++ b/ports_arch/ARMv7-M/threadx/iar/src/tx_thread_schedule.s @@ -9,6 +9,8 @@ * SPDX-License-Identifier: MIT **************************************************************************/ +// Portions of this file were generated with AI assistance. + /**************************************************************************/ /**************************************************************************/ @@ -132,7 +134,7 @@ __tx_ts_handler: BL _tx_execution_thread_exit // Call the thread exit function POP {r0, lr} // Recover LR #ifdef TX_PORT_USE_BASEPRI - MOV r0, 0 // Disable BASEPRI masking (enable interrupts) + MOV r0, #0 // Disable BASEPRI masking (enable interrupts) MSR BASEPRI, r0 #else CPSIE i // Enable interrupts @@ -260,9 +262,19 @@ __tx_ts_wait: #endif #ifdef TX_ENABLE_WFI +#ifdef TX_PORT_USE_BASEPRI + CPSID i // Mask every interrupt with PRIMASK, which WFI ignores + MOV r1, #0 // Clear BASEPRI so that an interrupt masked by it + MSR BASEPRI, r1 // is still able to wake the processor +#endif DSB // Ensure no outstanding memory transactions WFI // Wait for interrupt ISB // Ensure pipeline is flushed +#ifdef TX_PORT_USE_BASEPRI + LDR r1, =TX_PORT_BASEPRI // Restore the BASEPRI mask + MSR BASEPRI, r1 + CPSIE i // Clear PRIMASK; a pending interrupt is taken here +#endif #endif #ifdef TX_LOW_POWER diff --git a/ports_arch/ARMv7-M/threadx/iar/src/tx_thread_system_return.s b/ports_arch/ARMv7-M/threadx/iar/src/tx_thread_system_return.s index 65bec5a5..58be8f72 100644 --- a/ports_arch/ARMv7-M/threadx/iar/src/tx_thread_system_return.s +++ b/ports_arch/ARMv7-M/threadx/iar/src/tx_thread_system_return.s @@ -1,16 +1,19 @@ -/*************************************************************************** - * 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 - * https://opensource.org/licenses/MIT. - * - * SPDX-License-Identifier: MIT - **************************************************************************/ +;*************************************************************************** +;* 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 +;* https://opensource.org/licenses/MIT. +;* +;* SPDX-License-Identifier: MIT +;************************************************************************** +; Portions of this file were generated with AI assistance. + + +;************************************************************************** -/**************************************************************************/ /**************************************************************************/ /** */ /** ThreadX Component */ @@ -70,6 +73,8 @@ _tx_thread_system_return: MOV r0, #0x10000000 // Load PENDSVSET bit MOV r1, #0xE000E000 // Load NVIC base STR r0, [r1, #0xD04] // Set PENDSVBIT in ICSR + DSB SY // Ensure memory access is complete + ISB SY // Flush pipeline MRS r0, IPSR // Pickup IPSR CMP r0, #0 // Is it a thread returning? BNE _isr_context // If ISR, skip interrupt enable @@ -78,10 +83,12 @@ _tx_thread_system_return: MOV r0, #0 MSR BASEPRI, r0 // Enable interrupts MSR BASEPRI, r1 // Restore original interrupt posture + ISB SY // Flush pipeline #else MRS r1, PRIMASK // Thread context returning, pickup PRIMASK CPSIE i // Enable interrupts MSR PRIMASK, r1 // Restore original interrupt posture + ISB SY // Flush pipeline #endif _isr_context: BX lr // Return to caller diff --git a/ports_arch/ARMv7-M/threadx/inc/tx_port.h b/ports_arch/ARMv7-M/threadx/inc/tx_port.h index ac21ab55..d3d4771c 100644 --- a/ports_arch/ARMv7-M/threadx/inc/tx_port.h +++ b/ports_arch/ARMv7-M/threadx/inc/tx_port.h @@ -9,6 +9,8 @@ * SPDX-License-Identifier: MIT **************************************************************************/ +// Portions of this file were generated with AI assistance. + /**************************************************************************/ /**************************************************************************/ @@ -539,8 +541,9 @@ unsigned int posture; #ifdef TX_PORT_USE_BASEPRI __attribute__( ( always_inline ) ) static inline void __set_basepri_value(unsigned int basepri_value) { - __asm__ volatile ("MSR BASEPRI,%0 ": : "r" (basepri_value)); + __asm__ volatile ("MSR BASEPRI,%0 ": : "r" (basepri_value) : "memory"); } + #else __attribute__( ( always_inline ) ) static inline void __enable_interrupts(void) { @@ -552,7 +555,7 @@ __attribute__( ( always_inline ) ) static inline void __restore_interrupt(unsign { #ifdef TX_PORT_USE_BASEPRI __set_basepri_value(int_posture); - //__asm__ volatile ("MSR BASEPRI,%0": : "r" (int_posture): "memory"); + __asm__ volatile ("" : : : "memory"); #else __asm__ volatile ("MSR PRIMASK,%0": : "r" (int_posture): "memory"); #endif @@ -578,6 +581,7 @@ unsigned int interrupt_save; /* Set PendSV to invoke ThreadX scheduler. */ *((volatile ULONG *) 0xE000ED04) = ((ULONG) 0x10000000); + __asm__ volatile ("dsb sy \n isb sy " : : : "memory"); if (__get_ipsr_value() == 0) { interrupt_save = __get_interrupt_posture(); @@ -587,6 +591,7 @@ unsigned int interrupt_save; __enable_interrupts(); #endif __restore_interrupt(interrupt_save); + __asm__ volatile ("isb sy " : : : "memory"); } } @@ -699,7 +704,7 @@ void tx_thread_fpu_disable(void); #ifdef TX_THREAD_INIT CHAR _tx_version_id[] = - "(c) 2024 Microsoft Corp. (c) 2026-present Eclipse ThreadX contributors. * ThreadX Cortex-Mx Version 6.5.1.202602a *"; + "(c) 2024 Microsoft Corp. (c) 2026-present Eclipse ThreadX contributors. * ThreadX Cortex-Mx Version 6.5.2.202603 *"; #else #ifdef TX_MISRA_ENABLE extern CHAR _tx_version_id[100]; diff --git a/ports_arch/ARMv7-M/threadx_modules/ac5/module_manager/src/tx_thread_schedule.s b/ports_arch/ARMv7-M/threadx_modules/ac5/module_manager/src/tx_thread_schedule.s index c8f6e81d..bff9e4fd 100644 --- a/ports_arch/ARMv7-M/threadx_modules/ac5/module_manager/src/tx_thread_schedule.s +++ b/ports_arch/ARMv7-M/threadx_modules/ac5/module_manager/src/tx_thread_schedule.s @@ -9,6 +9,8 @@ * SPDX-License-Identifier: MIT **************************************************************************/ +// Portions of this file were generated with AI assistance. + /**************************************************************************/ /**************************************************************************/ @@ -206,7 +208,7 @@ MemManage_Handler STR r1, [r0] // Store ICSR DSB // Wait for memory access to complete #ifdef TX_PORT_USE_BASEPRI - MOV r0, 0 // Disable BASEPRI masking (enable interrupts) + MOV r0, #0 // Disable BASEPRI masking (enable interrupts) MSR BASEPRI, r0 #else CPSIE i // Enable interrupts @@ -238,7 +240,7 @@ __tx_ts_handler BL _tx_execution_thread_exit // Call the thread exit function POP {r0, lr} // Recover LR #ifdef TX_PORT_USE_BASEPRI - MOV r0, 0 // Disable BASEPRI masking (enable interrupts) + MOV r0, #0 // Disable BASEPRI masking (enable interrupts) MSR BASEPRI, r0 #else CPSIE i // Enable interrupts @@ -318,9 +320,19 @@ __tx_ts_wait #endif #ifdef TX_ENABLE_WFI +#ifdef TX_PORT_USE_BASEPRI + CPSID i // Mask every interrupt with PRIMASK, which WFI ignores + MOV r1, #0 // Clear BASEPRI so that an interrupt masked by it + MSR BASEPRI, r1 // is still able to wake the processor +#endif DSB // Ensure no outstanding memory transactions WFI // Wait for interrupt ISB // Ensure pipeline is flushed +#ifdef TX_PORT_USE_BASEPRI + LDR r1, =TX_PORT_BASEPRI // Restore the BASEPRI mask + MSR BASEPRI, r1 + CPSIE i // Clear PRIMASK; a pending interrupt is taken here +#endif #endif #ifdef TX_LOW_POWER diff --git a/ports_arch/ARMv7-M/threadx_modules/ac6/module_manager/src/tx_thread_schedule.S b/ports_arch/ARMv7-M/threadx_modules/ac6/module_manager/src/tx_thread_schedule.S index 1330dde3..77a7484f 100644 --- a/ports_arch/ARMv7-M/threadx_modules/ac6/module_manager/src/tx_thread_schedule.S +++ b/ports_arch/ARMv7-M/threadx_modules/ac6/module_manager/src/tx_thread_schedule.S @@ -8,6 +8,7 @@ * * SPDX-License-Identifier: MIT **************************************************************************/ +// Portions of this file were generated with AI assistance. /**************************************************************************/ @@ -217,7 +218,7 @@ UsageFault_Handler: STR r1, [r0] // Store ICSR DSB // Wait for memory access to complete #ifdef TX_PORT_USE_BASEPRI - MOV r0, 0 // Disable BASEPRI masking (enable interrupts) + MOV r0, #0 // Disable BASEPRI masking (enable interrupts) MSR BASEPRI, r0 #else CPSIE i // Enable interrupts @@ -252,7 +253,7 @@ __tx_ts_handler: BL _tx_execution_thread_exit // Call the thread exit function POP {r0, lr} // Recover LR #ifdef TX_PORT_USE_BASEPRI - MOV r0, 0 // Disable BASEPRI masking (enable interrupts) + MOV r0, #0 // Disable BASEPRI masking (enable interrupts) MSR BASEPRI, r0 #else CPSIE i // Enable interrupts @@ -332,9 +333,19 @@ __tx_ts_wait: #endif #ifdef TX_ENABLE_WFI +#ifdef TX_PORT_USE_BASEPRI + CPSID i // Mask every interrupt with PRIMASK, which WFI ignores + MOV r1, #0 // Clear BASEPRI so that an interrupt masked by it + MSR BASEPRI, r1 // is still able to wake the processor +#endif DSB // Ensure no outstanding memory transactions WFI // Wait for interrupt ISB // Ensure pipeline is flushed +#ifdef TX_PORT_USE_BASEPRI + LDR r1, =TX_PORT_BASEPRI // Restore the BASEPRI mask + MSR BASEPRI, r1 + CPSIE i // Clear PRIMASK; a pending interrupt is taken here +#endif #endif #ifdef TX_LOW_POWER diff --git a/ports_arch/ARMv7-M/threadx_modules/gnu/module_manager/src/tx_thread_schedule.S b/ports_arch/ARMv7-M/threadx_modules/gnu/module_manager/src/tx_thread_schedule.S index dffca713..ad2ad8f0 100644 --- a/ports_arch/ARMv7-M/threadx_modules/gnu/module_manager/src/tx_thread_schedule.S +++ b/ports_arch/ARMv7-M/threadx_modules/gnu/module_manager/src/tx_thread_schedule.S @@ -8,6 +8,7 @@ * * SPDX-License-Identifier: MIT **************************************************************************/ +// Portions of this file were generated with AI assistance. /**************************************************************************/ @@ -215,7 +216,7 @@ UsageFault_Handler: STR r1, [r0] // Store ICSR DSB // Wait for memory access to complete #ifdef TX_PORT_USE_BASEPRI - MOV r0, 0 // Disable BASEPRI masking (enable interrupts) + MOV r0, #0 // Disable BASEPRI masking (enable interrupts) MSR BASEPRI, r0 #else CPSIE i // Enable interrupts @@ -250,7 +251,7 @@ __tx_ts_handler: BL _tx_execution_thread_exit // Call the thread exit function POP {r0, lr} // Recover LR #ifdef TX_PORT_USE_BASEPRI - MOV r0, 0 // Disable BASEPRI masking (enable interrupts) + MOV r0, #0 // Disable BASEPRI masking (enable interrupts) MSR BASEPRI, r0 #else CPSIE i // Enable interrupts @@ -330,9 +331,19 @@ __tx_ts_wait: #endif #ifdef TX_ENABLE_WFI +#ifdef TX_PORT_USE_BASEPRI + CPSID i // Mask every interrupt with PRIMASK, which WFI ignores + MOV r1, #0 // Clear BASEPRI so that an interrupt masked by it + MSR BASEPRI, r1 // is still able to wake the processor +#endif DSB // Ensure no outstanding memory transactions WFI // Wait for interrupt ISB // Ensure pipeline is flushed +#ifdef TX_PORT_USE_BASEPRI + LDR r1, =TX_PORT_BASEPRI // Restore the BASEPRI mask + MSR BASEPRI, r1 + CPSIE i // Clear PRIMASK; a pending interrupt is taken here +#endif #endif #ifdef TX_LOW_POWER diff --git a/ports_arch/ARMv7-M/threadx_modules/iar/module_manager/src/tx_iar.c b/ports_arch/ARMv7-M/threadx_modules/iar/module_manager/src/tx_iar.c index 238b485e..ab6c209c 100644 --- a/ports_arch/ARMv7-M/threadx_modules/iar/module_manager/src/tx_iar.c +++ b/ports_arch/ARMv7-M/threadx_modules/iar/module_manager/src/tx_iar.c @@ -9,6 +9,7 @@ * SPDX-License-Identifier: MIT **************************************************************************/ +// Portions of this file were generated with AI assistance. /**************************************************************************/ /**************************************************************************/ @@ -270,7 +271,7 @@ TX_MUTEX *mutex_ptr; mutex_ptr = &__tx_iar_file_lock_mutexes[__tx_iar_file_lock_next_free_mutex++]; /* Check for wrap-around on the next free mutex. */ - if (__tx_iar_file_lock_next_free_mutex >= _MAX_LOCK) + if (__tx_iar_file_lock_next_free_mutex >= _MAX_FLOCK) { /* Yes, set the free index back to 0. */ @@ -287,7 +288,7 @@ TX_MUTEX *mutex_ptr; } /* Determine if a free mutex was found. */ - if (i >= _MAX_LOCK) + if (i >= _MAX_FLOCK) { /* Error! No more free mutexes! */ @@ -678,7 +679,7 @@ TX_MUTEX *mutex_ptr; mutex_ptr = &__tx_iar_file_lock_mutexes[__tx_iar_file_lock_next_free_mutex++]; /* Check for wrap-around on the next free mutex. */ - if (__tx_iar_file_lock_next_free_mutex >= _MAX_LOCK) + if (__tx_iar_file_lock_next_free_mutex >= _MAX_FLOCK) { /* Yes, set the free index back to 0. */ @@ -695,7 +696,7 @@ TX_MUTEX *mutex_ptr; } /* Determine if a free mutex was found. */ - if (i >= _MAX_LOCK) + if (i >= _MAX_FLOCK) { /* Error! No more free mutexes! */ diff --git a/ports_arch/ARMv7-M/threadx_modules/iar/module_manager/src/tx_thread_schedule.s b/ports_arch/ARMv7-M/threadx_modules/iar/module_manager/src/tx_thread_schedule.s index 7b30b360..00a27925 100644 --- a/ports_arch/ARMv7-M/threadx_modules/iar/module_manager/src/tx_thread_schedule.s +++ b/ports_arch/ARMv7-M/threadx_modules/iar/module_manager/src/tx_thread_schedule.s @@ -9,6 +9,8 @@ * SPDX-License-Identifier: MIT **************************************************************************/ +// Portions of this file were generated with AI assistance. + /**************************************************************************/ /**************************************************************************/ @@ -207,7 +209,7 @@ UsageFault_Handler: STR r1, [r0] // Store ICSR DSB // Wait for memory access to complete #ifdef TX_PORT_USE_BASEPRI - MOV r0, 0 // Disable BASEPRI masking (enable interrupts) + MOV r0, #0 // Disable BASEPRI masking (enable interrupts) MSR BASEPRI, r0 #else CPSIE i // Enable interrupts @@ -239,7 +241,7 @@ __tx_ts_handler: BL _tx_execution_thread_exit // Call the thread exit function POP {r0, lr} // Recover LR #ifdef TX_PORT_USE_BASEPRI - MOV r0, 0 // Disable BASEPRI masking (enable interrupts) + MOV r0, #0 // Disable BASEPRI masking (enable interrupts) MSR BASEPRI, r0 #else CPSIE i // Enable interrupts @@ -319,9 +321,19 @@ __tx_ts_wait: #endif #ifdef TX_ENABLE_WFI +#ifdef TX_PORT_USE_BASEPRI + CPSID i // Mask every interrupt with PRIMASK, which WFI ignores + MOV r1, #0 // Clear BASEPRI so that an interrupt masked by it + MSR BASEPRI, r1 // is still able to wake the processor +#endif DSB // Ensure no outstanding memory transactions WFI // Wait for interrupt ISB // Ensure pipeline is flushed +#ifdef TX_PORT_USE_BASEPRI + LDR r1, =TX_PORT_BASEPRI // Restore the BASEPRI mask + MSR BASEPRI, r1 + CPSIE i // Clear PRIMASK; a pending interrupt is taken here +#endif #endif #ifdef TX_LOW_POWER diff --git a/ports_arch/ARMv7-M/threadx_modules/inc/tx_port.h b/ports_arch/ARMv7-M/threadx_modules/inc/tx_port.h index 746586f3..1675be09 100644 --- a/ports_arch/ARMv7-M/threadx_modules/inc/tx_port.h +++ b/ports_arch/ARMv7-M/threadx_modules/inc/tx_port.h @@ -711,7 +711,7 @@ void tx_thread_fpu_disable(void); #ifdef TX_THREAD_INIT CHAR _tx_version_id[] = - "(c) 2024 Microsoft Corp. (c) 2026-present Eclipse ThreadX contributors. * ThreadX Cortex-Mx Version 6.5.1.202602a *"; + "(c) 2024 Microsoft Corp. (c) 2026-present Eclipse ThreadX contributors. * ThreadX Cortex-Mx Version 6.5.2.202603 *"; #else #ifdef TX_MISRA_ENABLE extern CHAR _tx_version_id[100]; diff --git a/ports_arch/ARMv8-A/threadx/common/inc/tx_port.h b/ports_arch/ARMv8-A/threadx/common/inc/tx_port.h index 4487de47..691fedd8 100644 --- a/ports_arch/ARMv8-A/threadx/common/inc/tx_port.h +++ b/ports_arch/ARMv8-A/threadx/common/inc/tx_port.h @@ -361,7 +361,7 @@ VOID tx_thread_fp_disable(VOID); #ifdef TX_THREAD_INIT CHAR _tx_version_id[] = - "(c) 2024 Microsoft Corp. (c) 2026-present Eclipse ThreadX contributors. * ThreadX ARMv8-A Version 6.5.1.202602a *"; + "(c) 2024 Microsoft Corp. (c) 2026-present Eclipse ThreadX contributors. * ThreadX ARMv8-A Version 6.5.2.202603 *"; #else extern CHAR _tx_version_id[]; #endif diff --git a/ports_arch/ARMv8-A/threadx/ports/ac6/example_build/sample_threadx/sample_threadx.launch b/ports_arch/ARMv8-A/threadx/ports/ac6/example_build/sample_threadx/sample_threadx.launch index 4aff966d..39d30548 100644 --- a/ports_arch/ARMv8-A/threadx/ports/ac6/example_build/sample_threadx/sample_threadx.launch +++ b/ports_arch/ARMv8-A/threadx/ports/ac6/example_build/sample_threadx/sample_threadx.launch @@ -181,7 +181,7 @@ <booleanAttribute key="VFS_ENABLED" value="true"/> <stringAttribute key="VFS_LOCAL_DIR" value="${workspace_loc}"/> <stringAttribute key="VFS_REMOTE_MOUNT" value="/writeable"/> - <stringAttribute key="breakpoints" value="<?xml version="1.0" encoding="UTF-8"?> <breakpoints order="ALPHA"> 	<breakpoint ignorecount="0" threadenabled="no" core_list="" continue="no" verboseBreakpoints="yes" kind="SOURCEPOSITION"> 		<master_location index="0" enabled="true" version="2" address="EL3:0x00000000800088D0" debugFile="C:/Users/andrejm/work/git/AzureRTOS/threadx_andrejm_armv8a/ports/cortex_a35/ac6/example_build/sample_threadx/sample_threadx.c" hostFile="C:\Users\andrejm\work\git\AzureRTOS\threadx_andrejm_armv8a\ports\cortex_a35\ac6\example_build\sample_threadx\sample_threadx.c" line="212" function="thread_0_entry"/> 		<location index="0" enabled="true" version="2" address="EL3:0x00000000800088D0" debugFile="C:/Users/andrejm/work/git/AzureRTOS/threadx_andrejm_armv8a/ports/cortex_a35/ac6/example_build/sample_threadx/sample_threadx.c" hostFile="C:\Users\andrejm\work\git\AzureRTOS\threadx_andrejm_armv8a\ports\cortex_a35\ac6\example_build\sample_threadx\sample_threadx.c" line="212" function="thread_0_entry"/> 		<location index="1" enabled="true" version="2" address="EL1N:0x00000000800088D0" debugFile="C:/Users/andrejm/work/git/AzureRTOS/threadx_andrejm_armv8a/ports/cortex_a35/ac6/example_build/sample_threadx/sample_threadx.c" hostFile="C:\Users\andrejm\work\git\AzureRTOS\threadx_andrejm_armv8a\ports\cortex_a35\ac6\example_build\sample_threadx\sample_threadx.c" line="212" function="thread_0_entry"/> 	</breakpoint> </breakpoints> "/> + <stringAttribute key="breakpoints" value="<?xml version="1.0" encoding="UTF-8"?> <breakpoints order="ALPHA"> </breakpoints> "/> <listAttribute key="com.arm.debug.views.common.AddressTracker.debugger.view.DisassemblyView.addresses"> <listEntry value="<Next Instruction>"/> <listEntry value=""/> @@ -311,15 +311,10 @@ <stringAttribute key="os_extension_id" value="com.arm.debug.os.threadx"/> <booleanAttribute key="runAfterConnect" value="false"/> <stringAttribute key="runTargetInitializationScript" value="${workspace_loc:/sample_threadx/use_model_semihosting.ds}"/> - <mapAttribute key="scripts_view_script_links"> - <mapEntry key="C:\Users\andrejm\work\git\AzureRTOS\threadx_andrejm_armv8a\ports\cortex_a35\ac6\example_build\sample_threadx\use_model_semihosting.ds" value=""/> - <mapEntry key="C:\Users\nisohack\Documents\work\x-ware_libs\threadx\ports\cortex_a35\ac6\example_build\sample_threadx\use_model_semihosting.ds" value=""/> - </mapAttribute> <listAttribute key="setup"> <listEntry value="CDB://Scripts/rtsm_launcher.py"/> <listEntry value=""FVP_Base_Cortex-A35x1""/> </listAttribute> <stringAttribute key="stopAtExpression" value="*$ENTRYPOINT"/> - <stringAttribute key="substitutePath" value="<?xml version="1.0" encoding="UTF-8"?> <tuplelist> 	<tuple> 		<ta>C:\temp1702\tx\</ta> 		<tb>C:\temp1702\tx\</tb> 	</tuple> </tuplelist> "/> <stringAttribute key="watchpoints" value="<?xml version="1.0" encoding="UTF-8"?> <watchpoints> </watchpoints> "/> </launchConfiguration> diff --git a/ports_arch/ARMv8-A/threadx/ports/gnu/CMakeLists.txt b/ports_arch/ARMv8-A/threadx/ports/gnu/CMakeLists.txt new file mode 100644 index 00000000..972c10f1 --- /dev/null +++ b/ports_arch/ARMv8-A/threadx/ports/gnu/CMakeLists.txt @@ -0,0 +1,30 @@ +# Copyright (c) 2026 Eclipse ThreadX contributors +# SPDX-License-Identifier: MIT +# Portions of this file were generated with AI assistance. +# +# ThreadX port sources for the AArch64 cores, GNU tools. +# Copied into every AArch64 gnu port by update.sh, so edit it here. + +target_sources(${PROJECT_NAME} + PRIVATE + # {{BEGIN_TARGET_SOURCES}} + ${CMAKE_CURRENT_LIST_DIR}/src/tx_initialize_low_level.S + ${CMAKE_CURRENT_LIST_DIR}/src/tx_thread_context_restore.S + ${CMAKE_CURRENT_LIST_DIR}/src/tx_thread_context_save.S + ${CMAKE_CURRENT_LIST_DIR}/src/tx_thread_fp_disable.c + ${CMAKE_CURRENT_LIST_DIR}/src/tx_thread_fp_enable.c + ${CMAKE_CURRENT_LIST_DIR}/src/tx_thread_interrupt_control.S + ${CMAKE_CURRENT_LIST_DIR}/src/tx_thread_interrupt_disable.S + ${CMAKE_CURRENT_LIST_DIR}/src/tx_thread_interrupt_restore.S + ${CMAKE_CURRENT_LIST_DIR}/src/tx_thread_schedule.S + ${CMAKE_CURRENT_LIST_DIR}/src/tx_thread_stack_build.S + ${CMAKE_CURRENT_LIST_DIR}/src/tx_thread_system_return.S + ${CMAKE_CURRENT_LIST_DIR}/src/tx_timer_interrupt.S + # {{END_TARGET_SOURCES}} +) + +target_include_directories(${PROJECT_NAME} + SYSTEM + PUBLIC + ${CMAKE_CURRENT_LIST_DIR}/inc +) diff --git a/ports_arch/ARMv8-A/threadx/ports/gnu/example_build/build_threadx.sh b/ports_arch/ARMv8-A/threadx/ports/gnu/example_build/build_threadx.sh new file mode 100755 index 00000000..b3b2cd36 --- /dev/null +++ b/ports_arch/ARMv8-A/threadx/ports/gnu/example_build/build_threadx.sh @@ -0,0 +1,87 @@ +#!/bin/bash +############################################################################## +# Copyright (c) 2026 Eclipse ThreadX contributors +# +# This program and the accompanying materials are made available under the +# terms of the MIT License which is available at +# https://opensource.org/licenses/MIT. +# +# AI Disclosure: This file was largely AI-generated by Claude Code (Opus 5). +# The AI-generated portions may be considered public domain (CC0-1.0) +# and not subject to the project's licence. The human contributor has +# reviewed and verified that the code is correct. +# +# SPDX-License-Identifier: MIT and CC0-1.0 +############################################################################## + +# Builds the ThreadX library, tx.a, for the AArch64 port this script sits in. +# The AArch64 examples previously had no build driver at all and could only be +# built through Arm Development Studio project files. +# +# ./build_threadx.sh +# TOOLCHAIN=atfe ATFE_CLANG=/path/to/clang ./build_threadx.sh +# +# The CPU is derived from the directory this script lives in, so one script +# serves every AArch64 port rather than needing one copy per core. + +set -eu + +cd "$(dirname "$(realpath "$0")")" + +# ports/<core>/gnu/example_build -> up two levels is <core> -> the -mcpu name. +# The same example tree is copied into the SMP ports, where the core directory +# carries an _smp suffix and the kernel sources live in common_smp. +core="$(basename "$(cd ../.. && pwd)")" +case "${core}" in + *_smp) cpu="${core%_smp}"; common="common_smp" ;; + *) cpu="${core}"; common="common" ;; +esac +cpu="${cpu//_/-}" + +: "${TOOLCHAIN:=gnu}" +case "${TOOLCHAIN}" in + gnu) + CC="aarch64-none-elf-gcc" + AR="aarch64-none-elf-ar" + TARGET_FLAGS="" + ;; + atfe) + CC="${ATFE_CLANG:-clang}" + case "${CC}" in + */*) AR="$(dirname "${CC}")/llvm-ar" ;; + *) AR="llvm-ar" ;; + esac + TARGET_FLAGS="--target=aarch64-none-elf" + ;; + *) + echo "Unknown TOOLCHAIN '${TOOLCHAIN}'; expected gnu or atfe" >&2 + exit 1 + ;; +esac + +CFLAGS="-g -mcpu=${cpu} -I../../../../${common}/inc -I../inc" + +echo "Building tx.a for ${cpu} with ${TOOLCHAIN}" + +rm -f tx.a ./*.o + +# Port sources. The SMP ports carry C sources here as well as assembly. +for src in ../src/*.S ../src/*.c; do + [ -f "${src}" ] || continue + obj="$(basename "${src}")" + "${CC}" ${TARGET_FLAGS} -c ${CFLAGS} "${src}" -o "${obj%.*}.o" +done + +# Common ThreadX sources. tx_misra.c is deliberately excluded: it is only for +# MISRA builds and has an assembly counterpart in the port. +for src in ../../../../${common}/src/*.c; do + case "$(basename "${src}")" in + tx_misra.c) continue ;; + esac + "${CC}" ${TARGET_FLAGS} -c ${CFLAGS} "${src}" -o "$(basename "${src%.c}").o" +done + +"${AR}" -rcs tx.a ./*.o +rm -f ./*.o + +echo "Done: $(basename "$(pwd)")/tx.a" diff --git a/ports_arch/ARMv8-A/threadx/ports/gnu/example_build/build_threadx_sample.sh b/ports_arch/ARMv8-A/threadx/ports/gnu/example_build/build_threadx_sample.sh new file mode 100755 index 00000000..94248a88 --- /dev/null +++ b/ports_arch/ARMv8-A/threadx/ports/gnu/example_build/build_threadx_sample.sh @@ -0,0 +1,109 @@ +#!/bin/bash +############################################################################## +# Copyright (c) 2026 Eclipse ThreadX contributors +# +# This program and the accompanying materials are made available under the +# terms of the MIT License which is available at +# https://opensource.org/licenses/MIT. +# +# AI Disclosure: This file was largely AI-generated by Claude Code (Opus 5). +# The AI-generated portions may be considered public domain (CC0-1.0) +# and not subject to the project's licence. The human contributor has +# reviewed and verified that the code is correct. +# +# SPDX-License-Identifier: MIT and CC0-1.0 +############################################################################## + +# Builds the sample image for the AArch64 port this script sits in. Run +# build_threadx.sh first, which produces tx.a. +# +# ./build_threadx_sample.sh +# TOOLCHAIN=atfe ATFE_CLANG=/path/to/clang ./build_threadx_sample.sh +# +# The sample targets a fixed virtual platform: a GICv3 interrupt controller and +# an SP804 timer at the Base platform addresses. It is not expected to run on +# other models or on hardware without changing those addresses. + +set -eu + +cd "$(dirname "$(realpath "$0")")" + +core="$(basename "$(cd ../.. && pwd)")" +case "${core}" in + *_smp) cpu="${core%_smp}"; common="common_smp" ;; + *) cpu="${core}"; common="common" ;; +esac +cpu="${cpu//_/-}" + +: "${TOOLCHAIN:=gnu}" +case "${TOOLCHAIN}" in + gnu) + CC="aarch64-none-elf-gcc" + TARGET_FLAGS="" + # rdimon supplies the semihosting syscalls and, with them, the real + # initialise_monitor_handles that startup.S calls. + SYSCALL_LIB="--specs=rdimon.specs" + SEMIHOST_STUB="" + # crti.o defines _init and _fini; crtn.o closes them. The link below + # passes -nostartfiles, which is right for a port with its own reset + # path but also drops these two, and startup.S calls + # __libc_init_array, whose newlib implementation calls _init. Without + # them every AArch64 sample failed to link: + # + # libg.a(libc_a-init.o): in function `__libc_init_array': + # undefined reference to `_init' + # relocation truncated to fit: R_AARCH64_CALL26 against undefined + # symbol `_init' + # + # crti.o must precede every other .init contribution and crtn.o must + # follow all of them, which is why they bracket the object list rather + # than sitting with the other flags. The AArch32 scripts need none of + # this: they use nosys.specs and never reach __libc_init_array. + CRT_BEGIN="$("${CC}" -mcpu="${cpu}" -print-file-name=crti.o)" + CRT_END="$("${CC}" -mcpu="${cpu}" -print-file-name=crtn.o)" + ;; + atfe) + CC="${ATFE_CLANG:-clang}" + TARGET_FLAGS="--target=aarch64-none-elf" + SYSCALL_LIB="-lsemihost" + # picolibc has no initialise_monitor_handles, and neither does the + # toolchain's semihosting library, so the weak stub stands in for it. + SEMIHOST_STUB="sample_threadx/semihost_stub.S" + # Deliberately empty. picolibc's __libc_init_array does not call _init, + # so these images link today and adding crti.o would change a working + # link for no reason. + CRT_BEGIN="" + CRT_END="" + ;; + *) + echo "Unknown TOOLCHAIN '${TOOLCHAIN}'; expected gnu or atfe" >&2 + exit 1 + ;; +esac + +CFLAGS="-g -mcpu=${cpu} -I../../../../${common}/inc -I../inc -Isample_threadx" + +echo "Building the sample for ${cpu} with ${TOOLCHAIN}" + +objects="" +for src in sample_threadx/startup.S sample_threadx/vectors.S \ + sample_threadx/v8_aarch64.S sample_threadx/v8_utils.S \ + sample_threadx/MP_Mutexes.S ${SEMIHOST_STUB} \ + sample_threadx/GICv3_gicd.c sample_threadx/GICv3_gicr.c \ + sample_threadx/sp804_timer.c sample_threadx/timer_interrupts.c \ + sample_threadx/sample_threadx.c; do + [ -n "${src}" ] || continue + obj="$(basename "${src}")" + obj="${obj%.*}.o" + "${CC}" ${TARGET_FLAGS} -c ${CFLAGS} "${src}" -o "${obj}" + objects="${objects} ${obj}" +done + +"${CC}" ${TARGET_FLAGS} -g -mcpu="${cpu}" -nostartfiles \ + -T sample_threadx/sample_threadx.ld ${SYSCALL_LIB} \ + -o sample_threadx.out -Wl,-Map=sample_threadx.map \ + ${CRT_BEGIN} ${objects} tx.a ${CRT_END} + +rm -f ${objects} + +echo "Done: $(basename "$(pwd)")/sample_threadx.out" diff --git a/ports_arch/ARMv8-A/threadx/ports/gnu/example_build/readme.md b/ports_arch/ARMv8-A/threadx/ports/gnu/example_build/readme.md new file mode 100644 index 00000000..3c52a7da --- /dev/null +++ b/ports_arch/ARMv8-A/threadx/ports/gnu/example_build/readme.md @@ -0,0 +1,39 @@ +# AArch64 GNU example build + +Builds the ThreadX library and a sample image for the AArch64 port this +directory belongs to. + +```sh +./build_threadx.sh # the ThreadX library, tx.a +./build_threadx_sample.sh # the sample image, sample_threadx.out +``` + +Set `TOOLCHAIN=atfe` to build with Arm Toolchain for Embedded, which is LLVM +based, instead of the GNU toolchain: + +```sh +TOOLCHAIN=atfe ATFE_CLANG=/path/to/clang ./build_threadx.sh +TOOLCHAIN=atfe ATFE_CLANG=/path/to/clang ./build_threadx_sample.sh +``` + +Both scripts derive the `-mcpu` value and the kernel source directory from the +port directory they sit in, so one pair of scripts serves every AArch64 port, +SMP included. Before they existed these examples could only be built through the +Arm Development Studio project files beside them, which is why the `.cproject` +and `.launch` files remain. + +## What the sample targets + +A fixed virtual platform: a GICv3 interrupt controller and an SP804 timer at the +Base platform addresses, as set up by `startup.S`, `vectors.S` and the GICv3 +sources here. It will not run on a model or board that places those peripherals +elsewhere without changing the addresses. + +## Semihosting + +`startup.S` calls `initialise_monitor_handles` to open the standard file handles +over a debugger connection. The GNU toolchain provides it in libgloss, pulled in +by `--specs=rdimon.specs`. picolibc, which Arm Toolchain for Embedded ships, has +no equivalent and neither does its semihosting library, so `semihost_stub.S` +supplies a weak no-op for that toolchain only. A real definition always wins +over it. diff --git a/ports_arch/ARMv8-A/threadx/ports/gnu/example_build/sample_threadx/sample_threadx.launch b/ports_arch/ARMv8-A/threadx/ports/gnu/example_build/sample_threadx/sample_threadx.launch index 12938fd1..40477c01 100644 --- a/ports_arch/ARMv8-A/threadx/ports/gnu/example_build/sample_threadx/sample_threadx.launch +++ b/ports_arch/ARMv8-A/threadx/ports/gnu/example_build/sample_threadx/sample_threadx.launch @@ -184,7 +184,7 @@ <booleanAttribute key="VFS_ENABLED" value="true"/> <stringAttribute key="VFS_LOCAL_DIR" value="${workspace_loc}"/> <stringAttribute key="VFS_REMOTE_MOUNT" value="/writeable"/> - <stringAttribute key="breakpoints" value="<?xml version="1.0" encoding="UTF-8"?> <breakpoints order="ALPHA"> 	<breakpoint ignorecount="0" threadenabled="no" core_list="" continue="no" verboseBreakpoints="yes" kind="SOURCEPOSITION"> 		<master_location index="0" enabled="true" version="2" address="EL3:0x0000000080000800" debugFile="C:/Users/nisohack/Documents/work/x-ware_libs/threadx/ports/cortex_a35/gnu/example_build/sample_threadx/vectors.S" hostFile="C:\Users\nisohack\Documents\work\x-ware_libs\threadx\ports\cortex_a35\gnu\example_build\sample_threadx\vectors.S" line="27"/> 		<location index="0" enabled="true" version="2" address="EL3:0x0000000080000800" debugFile="C:/Users/nisohack/Documents/work/x-ware_libs/threadx/ports/cortex_a35/gnu/example_build/sample_threadx/vectors.S" hostFile="C:\Users\nisohack\Documents\work\x-ware_libs\threadx\ports\cortex_a35\gnu\example_build\sample_threadx\vectors.S" line="27"/> 		<location index="1" enabled="true" version="2" address="EL1N:0x0000000080000800" debugFile="C:/Users/nisohack/Documents/work/x-ware_libs/threadx/ports/cortex_a35/gnu/example_build/sample_threadx/vectors.S" hostFile="C:\Users\nisohack\Documents\work\x-ware_libs\threadx\ports\cortex_a35\gnu\example_build\sample_threadx\vectors.S" line="27"/> 	</breakpoint> </breakpoints> "/> + <stringAttribute key="breakpoints" value="<?xml version="1.0" encoding="UTF-8"?> <breakpoints order="ALPHA"> </breakpoints> "/> <listAttribute key="com.arm.debug.views.common.AddressTracker.debugger.view.DisassemblyView.addresses"> <listEntry value="<Next Instruction>"/> <listEntry value=""/> @@ -314,15 +314,10 @@ <stringAttribute key="model_params" value="-C bp.secure_memory=false -C cache_state_modelled=0"/> <booleanAttribute key="runAfterConnect" value="false"/> <stringAttribute key="runTargetInitializationScript" value="${workspace_loc:/sample_threadx/use_model_semihosting.ds}"/> - <mapAttribute key="scripts_view_script_links"> - <mapEntry key="C:\Users\nisohack\Documents\work\x-ware_libs\threadx\ports\cortex_a35\ac6\example_build\sample_threadx\use_model_semihosting.ds" value=""/> - <mapEntry key="C:\Users\nisohack\Documents\work\x-ware_libs\threadx\ports\cortex_a35\gnu\example_build\sample_threadx\use_model_semihosting.ds" value=""/> - </mapAttribute> <listAttribute key="setup"> <listEntry value="CDB://Scripts/rtsm_launcher.py"/> <listEntry value=""FVP_Base_Cortex-A35x1""/> </listAttribute> <stringAttribute key="stopAtExpression" value="*$ENTRYPOINT"/> - <stringAttribute key="substitutePath" value="<?xml version="1.0" encoding="UTF-8"?> <tuplelist> 	<tuple> 		<ta>C:\temp1702\tx\</ta> 		<tb>C:\temp1702\tx\</tb> 	</tuple> </tuplelist> "/> <stringAttribute key="watchpoints" value="<?xml version="1.0" encoding="UTF-8"?> <watchpoints> </watchpoints> "/> </launchConfiguration> diff --git a/ports_arch/ARMv8-A/threadx/ports/gnu/example_build/sample_threadx/semihost_stub.S b/ports_arch/ARMv8-A/threadx/ports/gnu/example_build/sample_threadx/semihost_stub.S new file mode 100644 index 00000000..c456875d --- /dev/null +++ b/ports_arch/ARMv8-A/threadx/ports/gnu/example_build/sample_threadx/semihost_stub.S @@ -0,0 +1,43 @@ +/*************************************************************************** + * Copyright (c) 2026 Eclipse ThreadX contributors + * + * This program and the accompanying materials are made available under the + * terms of the MIT License which is available at + * https://opensource.org/licenses/MIT. + * + * AI Disclosure: This file was largely AI-generated by Claude Code (Opus 5). + * The AI-generated portions may be considered public domain (CC0-1.0) + * and not subject to the project's licence. The human contributor has + * reviewed and verified that the code is correct. + * + * SPDX-License-Identifier: MIT and CC0-1.0 + **************************************************************************/ + +/**************************************************************************/ +/** */ +/** ThreadX Component */ +/** */ +/** ARMv8-A example semihosting stub */ +/** */ +/**************************************************************************/ + +/* startup.S calls initialise_monitor_handles to open the standard file handles + over a debugger connection. The GNU toolchain provides it in libgloss, which + --specs=rdimon.specs pulls in, so this file is linked only for the LLVM + toolchain: picolibc has no equivalent, and neither does the toolchain's own + semihosting library, so without it the sample does not link at all. + + The definition is weak, so a real one always wins if something provides it. + The sample writes nothing to the standard handles, so doing nothing here + costs it no output. */ + + .text + .balign 4 + + .weak initialise_monitor_handles + .type initialise_monitor_handles, %function +initialise_monitor_handles: + ret + .size initialise_monitor_handles, . - initialise_monitor_handles + + .end diff --git a/ports_arch/ARMv8-A/threadx/ports/gnu/src/tx_initialize_low_level.S b/ports_arch/ARMv8-A/threadx/ports/gnu/src/tx_initialize_low_level.S index 3025f12b..f86568c5 100644 --- a/ports_arch/ARMv8-A/threadx/ports/gnu/src/tx_initialize_low_level.S +++ b/ports_arch/ARMv8-A/threadx/ports/gnu/src/tx_initialize_low_level.S @@ -9,6 +9,7 @@ * SPDX-License-Identifier: MIT **************************************************************************/ +// Portions of this file were generated with AI assistance. /**************************************************************************/ /**************************************************************************/ @@ -83,7 +84,6 @@ _tx_initialize_low_level: LDR x0, =_tx_initialize_unused_memory // Pickup address of unused memory ptr LDR x1, =__top_of_ram // Pickup unused memory address - LDR x1, [x1] // STR x1, [x0] // Store unused memory address /* Done, return to caller. */ diff --git a/ports_arch/ARMv8-A/threadx_smp/common/inc/tx_port.h b/ports_arch/ARMv8-A/threadx_smp/common/inc/tx_port.h index e97d78d5..38c86cb2 100644 --- a/ports_arch/ARMv8-A/threadx_smp/common/inc/tx_port.h +++ b/ports_arch/ARMv8-A/threadx_smp/common/inc/tx_port.h @@ -411,7 +411,7 @@ VOID tx_thread_fp_disable(VOID); #ifdef TX_THREAD_INIT CHAR _tx_version_id[] = - "(c) 2024 Microsoft Corp. (c) 2026-present Eclipse ThreadX contributors. * ThreadX ARMv8-A-SMP Version 6.5.1.202602a *"; + "(c) 2024 Microsoft Corp. (c) 2026-present Eclipse ThreadX contributors. * ThreadX ARMv8-A-SMP Version 6.5.2.202603 *"; #else extern CHAR _tx_version_id[]; #endif diff --git a/ports_arch/ARMv8-A/threadx_smp/common/src/tx_thread_smp_time_get.S b/ports_arch/ARMv8-A/threadx_smp/common/src/tx_thread_smp_time_get.S index 335824fb..4bb9f1cb 100644 --- a/ports_arch/ARMv8-A/threadx_smp/common/src/tx_thread_smp_time_get.S +++ b/ports_arch/ARMv8-A/threadx_smp/common/src/tx_thread_smp_time_get.S @@ -9,6 +9,7 @@ * SPDX-License-Identifier: MIT **************************************************************************/ +// Portions of this file were generated with AI assistance. /**************************************************************************/ /**************************************************************************/ @@ -60,5 +61,5 @@ .global _tx_thread_smp_time_get .type _tx_thread_smp_time_get, @function _tx_thread_smp_time_get: - MOV x0, #0 // FIXME: Get timer + MRS x0, CNTPCT_EL0 // Read generic timer physical count RET diff --git a/ports_arch/ARMv8-A/threadx_smp/ports/ac6/example_build/sample_threadx/sample_threadx.launch b/ports_arch/ARMv8-A/threadx_smp/ports/ac6/example_build/sample_threadx/sample_threadx.launch index 5a0bdcf4..639e2f4e 100644 --- a/ports_arch/ARMv8-A/threadx_smp/ports/ac6/example_build/sample_threadx/sample_threadx.launch +++ b/ports_arch/ARMv8-A/threadx_smp/ports/ac6/example_build/sample_threadx/sample_threadx.launch @@ -214,17 +214,10 @@ <listEntry value="element formatter"/> <listEntry value="Hexadecimal"/> </listAttribute> - <listAttribute key="TREE_NODE_PROPERTIES:debugger.view.VariableTreeView"> - <listEntry value="NODE CACHE VERSION 1"/> - <listEntry value="LOCALS:Locals:VALUE:B:/support/broadcom/tx58cortexa53arm/release/threadx/tx/tx_thread_system_suspend.c::_tx_thread_system_suspend::possible_cores"/> - <listEntry value="1"/> - <listEntry value="formatter"/> - <listEntry value="Hexadecimal"/> - </listAttribute> <booleanAttribute key="VFS_ENABLED" value="true"/> <stringAttribute key="VFS_LOCAL_DIR" value="${workspace_loc}"/> <stringAttribute key="VFS_REMOTE_MOUNT" value="/writeable"/> - <stringAttribute key="breakpoints" value="<?xml version="1.0" encoding="UTF-8"?> <breakpoints order="ALPHA"> 	<breakpoint ignorecount="0" threadenabled="no" core_list="" continue="no" verboseBreakpoints="yes" kind="SOURCEPOSITION"> 		<master_location index="0" enabled="true" version="2" address="EL3:0x000000008000B64C" debugFile="C:/Users/andrejm/work/git/AzureRTOS/threadx_andrejm_armv8a/ports_smp/cortex_a35_smp/ac6/example_build/sample_threadx/sample_threadx.c" hostFile="C:\Users\andrejm\work\git\AzureRTOS\threadx_andrejm_armv8a\ports_smp\cortex_a35_smp\ac6\example_build\sample_threadx\sample_threadx.c" line="212" function="thread_0_entry"/> 		<location index="0" enabled="true" version="2" address="EL3:0x000000008000B64C" debugFile="C:/Users/andrejm/work/git/AzureRTOS/threadx_andrejm_armv8a/ports_smp/cortex_a35_smp/ac6/example_build/sample_threadx/sample_threadx.c" hostFile="C:\Users\andrejm\work\git\AzureRTOS\threadx_andrejm_armv8a\ports_smp\cortex_a35_smp\ac6\example_build\sample_threadx\sample_threadx.c" line="212" function="thread_0_entry"/> 		<location index="1" enabled="true" version="2" address="EL1N:0x000000008000B64C" debugFile="C:/Users/andrejm/work/git/AzureRTOS/threadx_andrejm_armv8a/ports_smp/cortex_a35_smp/ac6/example_build/sample_threadx/sample_threadx.c" hostFile="C:\Users\andrejm\work\git\AzureRTOS\threadx_andrejm_armv8a\ports_smp\cortex_a35_smp\ac6\example_build\sample_threadx\sample_threadx.c" line="212" function="thread_0_entry"/> 	</breakpoint> </breakpoints> "/> + <stringAttribute key="breakpoints" value="<?xml version="1.0" encoding="UTF-8"?> <breakpoints order="ALPHA"> </breakpoints> "/> <listAttribute key="com.arm.debug.views.common.AddressTracker.debugger.view.DisassemblyView.addresses"> <listEntry value=""/> <listEntry value="<Next Instruction>"/> @@ -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=""FVP_Base_Cortex-A35x4""/> </listAttribute> <stringAttribute key="stopAtExpression" value="*$ENTRYPOINT"/> - <stringAttribute key="substitutePath" value="<?xml version="1.0" encoding="UTF-8"?> <tuplelist> 	<tuple> 		<ta>C:/release/threadx/sample_threadx</ta> 		<tb>C:\release\threadx\sample_threadx\</tb> 	</tuple> 	<tuple> 		<ta>C:/release/threadx/tx</ta> 		<tb>C:\release\threadx\sample_threadx\</tb> 	</tuple> </tuplelist> "/> <stringAttribute key="watchpoints" value="<?xml version="1.0" encoding="UTF-8"?> <watchpoints> </watchpoints> "/> </launchConfiguration> diff --git a/ports_arch/ARMv8-A/threadx_smp/ports/gnu/CMakeLists.txt b/ports_arch/ARMv8-A/threadx_smp/ports/gnu/CMakeLists.txt new file mode 100644 index 00000000..36f7492b --- /dev/null +++ b/ports_arch/ARMv8-A/threadx_smp/ports/gnu/CMakeLists.txt @@ -0,0 +1,39 @@ +# Copyright (c) 2026 Eclipse ThreadX contributors +# SPDX-License-Identifier: MIT +# Portions of this file were generated with AI assistance. +# +# ThreadX SMP port sources for the AArch64 cores, GNU tools. +# Copied into every AArch64 gnu SMP port by update.sh, so edit it here. + +target_sources(${PROJECT_NAME} + PRIVATE + # {{BEGIN_TARGET_SOURCES}} + ${CMAKE_CURRENT_LIST_DIR}/src/tx_initialize_low_level.S + ${CMAKE_CURRENT_LIST_DIR}/src/tx_thread_context_restore.S + ${CMAKE_CURRENT_LIST_DIR}/src/tx_thread_context_save.S + ${CMAKE_CURRENT_LIST_DIR}/src/tx_thread_fp_disable.c + ${CMAKE_CURRENT_LIST_DIR}/src/tx_thread_fp_enable.c + ${CMAKE_CURRENT_LIST_DIR}/src/tx_thread_interrupt_control.S + ${CMAKE_CURRENT_LIST_DIR}/src/tx_thread_interrupt_disable.S + ${CMAKE_CURRENT_LIST_DIR}/src/tx_thread_interrupt_restore.S + ${CMAKE_CURRENT_LIST_DIR}/src/tx_thread_schedule.S + ${CMAKE_CURRENT_LIST_DIR}/src/tx_thread_smp_core_get.S + ${CMAKE_CURRENT_LIST_DIR}/src/tx_thread_smp_core_preempt.S + ${CMAKE_CURRENT_LIST_DIR}/src/tx_thread_smp_current_state_get.S + ${CMAKE_CURRENT_LIST_DIR}/src/tx_thread_smp_current_thread_get.S + ${CMAKE_CURRENT_LIST_DIR}/src/tx_thread_smp_initialize_wait.S + ${CMAKE_CURRENT_LIST_DIR}/src/tx_thread_smp_low_level_initialize.S + ${CMAKE_CURRENT_LIST_DIR}/src/tx_thread_smp_protect.S + ${CMAKE_CURRENT_LIST_DIR}/src/tx_thread_smp_time_get.S + ${CMAKE_CURRENT_LIST_DIR}/src/tx_thread_smp_unprotect.S + ${CMAKE_CURRENT_LIST_DIR}/src/tx_thread_stack_build.S + ${CMAKE_CURRENT_LIST_DIR}/src/tx_thread_system_return.S + ${CMAKE_CURRENT_LIST_DIR}/src/tx_timer_interrupt.S + # {{END_TARGET_SOURCES}} +) + +target_include_directories(${PROJECT_NAME} + SYSTEM + PUBLIC + ${CMAKE_CURRENT_LIST_DIR}/inc +) diff --git a/ports_arch/ARMv8-A/threadx_smp/ports/gnu/example_build/sample_threadx/sample_threadx.launch b/ports_arch/ARMv8-A/threadx_smp/ports/gnu/example_build/sample_threadx/sample_threadx.launch index d583631e..d06144eb 100644 --- a/ports_arch/ARMv8-A/threadx_smp/ports/gnu/example_build/sample_threadx/sample_threadx.launch +++ b/ports_arch/ARMv8-A/threadx_smp/ports/gnu/example_build/sample_threadx/sample_threadx.launch @@ -239,13 +239,6 @@ <listEntry value="element formatter"/> <listEntry value="Character"/> </listAttribute> - <listAttribute key="TREE_NODE_PROPERTIES:debugger.view.VariableTreeView"> - <listEntry value="NODE CACHE VERSION 1"/> - <listEntry value="LOCALS:Locals:VALUE:B:/support/broadcom/tx58cortexa53arm/release/threadx/tx/tx_thread_system_suspend.c::_tx_thread_system_suspend::possible_cores"/> - <listEntry value="1"/> - <listEntry value="formatter"/> - <listEntry value="Hexadecimal"/> - </listAttribute> <booleanAttribute key="VFS_ENABLED" value="true"/> <stringAttribute key="VFS_LOCAL_DIR" value="${workspace_loc}"/> <stringAttribute key="VFS_REMOTE_MOUNT" value="/writeable"/> @@ -424,22 +417,10 @@ <stringAttribute key="os_extension_id" value="com.arm.debug.os.threadx"/> <booleanAttribute key="runAfterConnect" value="false"/> <stringAttribute key="runTargetInitializationScript" value="${workspace_loc:/sample_threadx/use_model_semihosting.ds}"/> - <mapAttribute key="scripts_view_script_links"> - <mapEntry key="B:\support\broadcom\a53smp_el1_clean_mar25\sample_threadx\use_model_semihosting.ds" value=""/> - <mapEntry key="B:\support\broadcom\tx58cortexa53arm\release\threadx\sample_threadx\use_model_semihosting.ds" value=""/> - <mapEntry key="C:\Users\andrejm\work\git\AzureRTOS\threadx_other\ports_smp\cortex_a35_smp\gnu\example_build\sample_threadx\use_model_semihosting.ds" value=""/> - <mapEntry key="C:\Users\nisohack\Documents\work\x-ware_libs\threadx\ports_smp\cortex_a35_smp\gnu\example_build\sample_threadx\use_model_semihosting.ds" value=""/> - <mapEntry key="C:\Users\nisohack\Documents\work\x-ware_libs\threadx_github\ports\cortex_a5x_smp\gnu\example_build\common\use_model_semihosting.ds" value=""/> - <mapEntry key="D:\Documents\work\get_threadx-smp_cortex-a53_gnu_working\threadx_arm\threadx\common\use_model_semihosting.ds" value=""/> - <mapEntry key="D:\Documents\work\get_threadx-smp_cortex-a53_gnu_working\threadx_arm\threadx\sample_threadx\use_model_semihosting.ds" value=""/> - <mapEntry key="D:\Documents\work\get_threadx-smp_cortex-a53_gnu_working\threadx_official_workspace_no_sevice_packs\threadx\common\use_model_semihosting.ds" value=""/> - <mapEntry key="D:\Documents\work\get_threadx-smp_cortex-a53_gnu_working\threadx_official_workspaces_no_sevice_packs\threadx\common\use_model_semihosting.ds" value=""/> - </mapAttribute> <listAttribute key="setup"> <listEntry value="CDB://Scripts/rtsm_launcher.py"/> <listEntry value=""FVP_Base_Cortex-A35x4""/> </listAttribute> <stringAttribute key="stopAtExpression" value="*$ENTRYPOINT"/> - <stringAttribute key="substitutePath" value="<?xml version="1.0" encoding="UTF-8"?> <tuplelist> 	<tuple> 		<ta>/tmp/dgboter/bbs/dsggnu-vm-1-x86_64--mingw32-i686/buildbot/mingw32-i686--aarch64-elf/build/src/newlib-cygwin/libgloss/aarch64/</ta> 		<tb>D:\Documents\work\toolchains\newlib-cygwin\libgloss\aarch64\</tb> 	</tuple> 	<tuple> 		<ta>C:/release/threadx/sample_threadx</ta> 		<tb>C:\release\threadx\sample_threadx\</tb> 	</tuple> 	<tuple> 		<ta>C:/release/threadx/tx</ta> 		<tb>C:\release\threadx\sample_threadx\</tb> 	</tuple> </tuplelist> "/> <stringAttribute key="watchpoints" value="<?xml version="1.0" encoding="UTF-8"?> <watchpoints> </watchpoints> "/> </launchConfiguration> diff --git a/ports_arch/ARMv8-A/update.ps1 b/ports_arch/ARMv8-A/update.ps1 index 0663b603..98ba818d 100644 --- a/ports_arch/ARMv8-A/update.ps1 +++ b/ports_arch/ARMv8-A/update.ps1 @@ -77,7 +77,13 @@ Write-Verbose ("Copy regression test: $CopyRegressionTest") Write-Verbose ("Patch files: $PatchFiles") Write-Verbose ("LogDir: $LogDir") -$cores = @("cortex_a35", "cortex_a53", "cortex_a55", "cortex_a57", "cortex_a65", "cortex_a65ae", "cortex_a72", "cortex_a73", "cortex_a75", "cortex_a76", "cortex_a76ae", "cortex_a77") +$cores = @("cortex_a34", "cortex_a35", "cortex_a53", "cortex_a55", "cortex_a57", "cortex_a65", "cortex_a65ae", "cortex_a72", "cortex_a73", "cortex_a75", "cortex_a76", "cortex_a76ae", "cortex_a77") + +# Cortex-A78 ships as an SMP port only: ports_smp\cortex_a78_smp exists but +# ports\cortex_a78 does not. Listing it separately keeps the generator from +# creating a ThreadX port that the tree has never had. +$cores_smp_only = @("cortex_a78") + $compilers = @("ac6", "gnu") $patches = ( ('example_build\sample_threadx\.cproject', ( @@ -88,17 +94,26 @@ $patches = ( (('value="cortex-a35"'), ('value="cortex-$($core_short_lower)"')), (('Cortex-A35.AArch64.ARMv8.Neon.Crypto'), ('Cortex-$($core_short_upper).AArch64.ARMv8.Neon.Crypto')) )), + # The base_a35x<n> entries are the config database taxonomy id, which is + # spelt in lower case in the launch files. They used to read base_A35x<n>, + # which -creplace never matched, leaving every port pointing at the A35 + # platform. The Cortex-A35x<n> SMP entries are the activity name the SMP + # launch files use in place of "Debug Cortex-A35"; matching the " SMP" + # suffix keeps them from also rewriting the FVP model name. ('example_build\sample_threadx\sample_threadx.launch', ( ('Debug Cortex-A35', 'Debug Cortex-$($core_short_upper)'), ('Base_A35x1', 'Base_$($core_short_upper)x1'), - ('base_A35x1', 'base_$($core_short_lower)x1'), + ('base_a35x1', 'base_$($core_short_lower)x1'), ('FVP_Base_Cortex-A35x1', 'FVP_Base_Cortex-$($core_short_upper)x1'), + ('Cortex-A35x1 SMP', 'Cortex-$($core_short_upper)x1 SMP'), ('Base_A35x2', 'Base_$($core_short_upper)x2'), - ('base_A35x2', 'base_$($core_short_lower)x2'), + ('base_a35x2', 'base_$($core_short_lower)x2'), ('FVP_Base_Cortex-A35x2', 'FVP_Base_Cortex-$($core_short_upper)x2'), + ('Cortex-A35x2 SMP', 'Cortex-$($core_short_upper)x2 SMP'), ('Base_A35x4', 'Base_$($core_short_upper)x4'), - ('base_A35x4', 'base_$($core_short_lower)x4'), - ('FVP_Base_Cortex-A35x4', 'FVP_Base_Cortex-$($core_short_upper)x4') + ('base_a35x4', 'base_$($core_short_lower)x4'), + ('FVP_Base_Cortex-A35x4', 'FVP_Base_Cortex-$($core_short_upper)x4'), + ('Cortex-A35x4 SMP', 'Cortex-$($core_short_upper)x4 SMP') )) ) @@ -119,7 +134,13 @@ Function Copy-FilesVerbose { } ForEach ($PortSet in $PortSets) { - ForEach ($core in $cores) { + If ($PortSet -eq "tx_smp") { + $PortSetCores = $cores + $cores_smp_only + } Else { + $PortSetCores = $cores + } + + ForEach ($core in $PortSetCores) { Switch ($PortSet) { "tx" { $core_directory = "..\..\ports\" + $core } "tx_smp" { $core_directory = "..\..\ports_smp\" + $core + "_smp" } diff --git a/ports_arch/ARMv8-A/update.sh b/ports_arch/ARMv8-A/update.sh new file mode 100755 index 00000000..4084d33f --- /dev/null +++ b/ports_arch/ARMv8-A/update.sh @@ -0,0 +1,191 @@ +#!/bin/bash +############################################################################## +# Copyright (C) 2026 Eclipse ThreadX contributors +# +# This program and the accompanying materials are made available under the +# terms of the MIT License which is available at +# https://opensource.org/licenses/MIT. +# +# AI Disclosure: This file was largely AI-generated by Claude Code (Opus 5). +# The AI-generated portions may be considered public domain (CC0-1.0) +# and not subject to the project's licence. The human contributor has +# reviewed and verified that the code is correct. +# +# SPDX-License-Identifier: MIT and CC0-1.0 +############################################################################## + +# Update the ARMv8-A ports from the generic ARMv8-A port, generating ports and +# examples from the common files. This is a port of update.ps1 beside it, which +# needs PowerShell and so could only be run on Windows. The two are kept +# equivalent: same cores, same compilers, same copy sets and the same patches. +# +# To update the ThreadX ports for the source tree: +# ./update.sh --port-sets tx --copy-common-files --copy-port-files \ +# --copy-example --patch-files +# +# To update the ThreadX ports for the test tree: +# ./update.sh --port-sets tx --copy-common-files --copy-port-files \ +# --copy-example --copy-validation-test --copy-regression-test \ +# --patch-files +# +# --copy-example, --copy-validation-test and --copy-regression-test are +# accepted and ignored, exactly as in update.ps1, where they are declared as +# parameters but never consulted. They are kept so that both scripts take the +# same command line. + +set -eu + +cd "$(dirname "$(realpath "$0")")" + +cores="cortex_a34 cortex_a35 cortex_a53 cortex_a55 cortex_a57 cortex_a65 cortex_a65ae \ + cortex_a72 cortex_a73 cortex_a75 cortex_a76 cortex_a76ae cortex_a77" + +# Cortex-A78 ships as an SMP port only: ports_smp/cortex_a78_smp exists but +# ports/cortex_a78 does not. Listing it separately keeps the generator from +# creating a ThreadX port that the tree has never had. +cores_smp_only="cortex_a78" + +compilers="ac6 gnu" + +port_sets="" +copy_common_files=0 +copy_port_files=0 +patch_files=0 + +usage() { + sed -n '22,35p' "$0" + exit "${1:-1}" +} + +while [ "$#" -gt 0 ]; do + case "$1" in + --port-sets) + [ "$#" -ge 2 ] || { echo "Error: --port-sets needs a value" >&2; exit 1; } + port_sets="$(printf '%s' "$2" | tr ',' ' ')" + shift 2 + ;; + --copy-common-files) copy_common_files=1; shift ;; + --copy-port-files) copy_port_files=1; shift ;; + --patch-files) patch_files=1; shift ;; + # Accepted and ignored, as in update.ps1. + --copy-example|--copy-validation-test|--copy-regression-test) shift ;; + -h|--help) usage 0 ;; + *) echo "Error: unknown option '$1'" >&2; usage ;; + esac +done + +if [ -z "${port_sets}" ]; then + echo "Error: --port-sets is required" >&2 + usage +fi + +for port_set in ${port_sets}; do + case "${port_set}" in + tx|tx_smp|txm|txm_smp) ;; + *) echo "Error: invalid port set '${port_set}'" >&2; exit 1 ;; + esac +done + +echo "Update the ARMv8-A ports" + +# Copy the contents of a directory over a destination, creating what is missing +# and overwriting what is not. This mirrors Copy-Item -Recurse -Force, which +# merges into the destination rather than replacing it. +copy_files() { + source_dir="$1" + destination_directory="$2" + + if [ -d "${source_dir}" ]; then + cp -Rf "${source_dir}/." "${destination_directory}/" + fi +} + +# Replace every occurrence of a literal string in a file, leaving the file +# alone when it does not exist. Only the files named in the patch list below +# are ever touched. +patch_file() { + path="$1" + original="$2" + substitute="$3" + + [ -f "${path}" ] || return 0 + + original_escaped="$(printf '%s' "${original}" | sed -e 's/[][\.*^$/&]/\\&/g')" + substitute_escaped="$(printf '%s' "${substitute}" | sed -e 's/[\/&]/\\&/g')" + sed -i "s/${original_escaped}/${substitute_escaped}/g" "${path}" +} + +for port_set in ${port_sets}; do + case "${port_set}" in + tx_smp) port_set_cores="${cores} ${cores_smp_only}" ;; + *) port_set_cores="${cores}" ;; + esac + + for core in ${port_set_cores}; do + case "${port_set}" in + tx) core_directory="../../ports/${core}" ;; + tx_smp) core_directory="../../ports_smp/${core}_smp" ;; + txm) core_directory="../../ports_module/${core}" ;; + txm_smp) core_directory="../../ports_module_smp/${core}_smp" ;; + esac + + core_short="${core#cortex_}" + core_short_lower="$(printf '%s' "${core_short}" | tr '[:upper:]' '[:lower:]')" + core_short_upper="$(printf '%s' "${core_short}" | tr '[:lower:]' '[:upper:]')" + + for compiler in ${compilers}; do + destination_directory="${core_directory}/${compiler}" + mkdir -p "${destination_directory}" + + if [ "${copy_common_files}" -eq 1 ]; then + copy_files "threadx/common" "${destination_directory}" + fi + + if [ "${copy_port_files}" -eq 1 ]; then + copy_files "threadx/ports/${compiler}" "${destination_directory}" + fi + + if [ "${port_set}" = "tx_smp" ]; then + if [ "${copy_common_files}" -eq 1 ]; then + copy_files "threadx_smp/common" "${destination_directory}" + fi + if [ "${copy_port_files}" -eq 1 ]; then + copy_files "threadx_smp/ports/${compiler}" "${destination_directory}" + fi + fi + + if [ "${patch_files}" -eq 1 ]; then + neon='Cortex-A35.AArch64.ARMv8.Neon.Crypto' + + sample_cproject="${destination_directory}/example_build/sample_threadx/.cproject" + patch_file "${sample_cproject}" 'value="cortex-a35"' "value=\"cortex-${core_short_lower}\"" + patch_file "${sample_cproject}" "${neon}" "Cortex-${core_short_upper}.AArch64.ARMv8.Neon.Crypto" + + tx_cproject="${destination_directory}/example_build/tx/.cproject" + patch_file "${tx_cproject}" 'value="cortex-a35"' "value=\"cortex-${core_short_lower}\"" + patch_file "${tx_cproject}" "${neon}" "Cortex-${core_short_upper}.AArch64.ARMv8.Neon.Crypto" + + launch="${destination_directory}/example_build/sample_threadx/sample_threadx.launch" + patch_file "${launch}" 'Debug Cortex-A35' "Debug Cortex-${core_short_upper}" + for count in 1 2 4; do + patch_file "${launch}" "Base_A35x${count}" "Base_${core_short_upper}x${count}" + # The config database taxonomy id is spelt in lower case in + # the launch files, so the search string must be too. It + # used to read base_A35x, which matched nothing and left + # every port pointing at the A35 platform. The ARMv7-A + # generator gets this right, which is why its ports carry a + # per-core ve_cortex_a<n>x1 id. + patch_file "${launch}" "base_a35x${count}" "base_${core_short_lower}x${count}" + patch_file "${launch}" "FVP_Base_Cortex-A35x${count}" "FVP_Base_Cortex-${core_short_upper}x${count}" + # The SMP launch files name the activity "Cortex-A35x4 SMP" + # rather than "Debug Cortex-A35", so the rule above does not + # reach them. Match the " SMP" suffix so this cannot also + # rewrite the FVP model name handled on the line above. + patch_file "${launch}" "Cortex-A35x${count} SMP" "Cortex-${core_short_upper}x${count} SMP" + done + fi + done + done +done + +echo "Done." diff --git a/ports_arch/ARMv8-M/threadx/ac6/CMakeLists.txt b/ports_arch/ARMv8-M/threadx/ac6/CMakeLists.txt index 5ad3b8e7..81b479e0 100644 --- a/ports_arch/ARMv8-M/threadx/ac6/CMakeLists.txt +++ b/ports_arch/ARMv8-M/threadx/ac6/CMakeLists.txt @@ -16,6 +16,8 @@ target_sources(${PROJECT_NAME} PRIVATE ${CMAKE_CURRENT_LIST_DIR}/src/tx_timer_interrupt.S ) -target_include_directories(${PROJECT_NAME} PUBLIC +target_include_directories(${PROJECT_NAME} + SYSTEM + PUBLIC inc ) diff --git a/ports_arch/ARMv8-M/threadx/ac6/readme_threadx.txt b/ports_arch/ARMv8-M/threadx/ac6/readme_threadx.txt index 87556be5..e835b109 100644 --- a/ports_arch/ARMv8-M/threadx/ac6/readme_threadx.txt +++ b/ports_arch/ARMv8-M/threadx/ac6/readme_threadx.txt @@ -218,7 +218,12 @@ information associated with this specific port of ThreadX: 03-02-2021 The following files were changed/added for version 6.1.5: tx_port.h Added ULONG64_DEFINED -09-30-2020 Initial ThreadX 6.1 version for Cortex-Mxx using AC6 tools. +09-30-2020 Initial ThreadX 6.1 version of this Armv8-M port using AC6 tools. + + The dates above belong to this shared port, which every Armv8-M + core is generated from. They are not the date a particular core + gained a ThreadX port: that is when its name was added to + scripts/copy_armv8_m.sh. Copyright(c) 1996-2020 Microsoft Corporation diff --git a/ports_arch/ARMv8-M/threadx/ac6/src/tx_initialize_low_level.S b/ports_arch/ARMv8-M/threadx/ac6/src/tx_initialize_low_level.S index 9332b7e1..4e81ac67 100644 --- a/ports_arch/ARMv8-M/threadx/ac6/src/tx_initialize_low_level.S +++ b/ports_arch/ARMv8-M/threadx/ac6/src/tx_initialize_low_level.S @@ -8,6 +8,7 @@ * * SPDX-License-Identifier: MIT **************************************************************************/ +// Portions of this file were generated with AI assistance. /**************************************************************************/ @@ -87,25 +88,17 @@ _tx_initialize_low_level: ADD r1, r1, #4 // STR r1, [r0] // Setup first unused memory pointer - /* Setup Vector Table Offset Register. */ - MOV r0, #0xE000E000 // Build address of NVIC registers - LDR r1, =__Vectors // Pickup address of vector table - STR r1, [r0, #0xD08] // Set vector table address - /* Enable the cycle count register. */ LDR r0, =0xE0001000 // Build address of DWT register LDR r1, [r0] // Pickup the current value ORR r1, r1, #1 // Set the CYCCNTENA bit STR r1, [r0] // Enable the cycle count register - /* Set system stack pointer from vector value. */ - LDR r0, =_tx_thread_system_stack_ptr // Build address of system stack pointer - LDR r1, =__Vectors // Pickup address of vector table - LDR r1, [r1] // Pickup reset stack pointer - STR r1, [r0] // Save system stack pointer - /* Configure SysTick. */ MOV r0, #0xE000E000 // Build address of NVIC registers + MOV r1, #0 // Build value for SysTick reset + STR r1, [r0, #0x10] // Reset SysTick Control + STR r1, [r0, #0x18] // Reset SysTick Counter Value LDR r1, =SYSTICK_CYCLES STR r1, [r0, #0x14] // Setup SysTick Reload Value MOV r1, #0x7 // Build SysTick Control Enable Value diff --git a/ports_arch/ARMv8-M/threadx/ac6/src/tx_thread_schedule.S b/ports_arch/ARMv8-M/threadx/ac6/src/tx_thread_schedule.S index 40d3282b..ba34803a 100644 --- a/ports_arch/ARMv8-M/threadx/ac6/src/tx_thread_schedule.S +++ b/ports_arch/ARMv8-M/threadx/ac6/src/tx_thread_schedule.S @@ -8,6 +8,7 @@ * * SPDX-License-Identifier: MIT **************************************************************************/ +// Portions of this file were generated with AI assistance. /**************************************************************************/ @@ -129,7 +130,7 @@ __tx_ts_handler: BL _tx_execution_thread_exit // Call the thread exit function POP {r0, lr} // Recover LR #ifdef TX_PORT_USE_BASEPRI - MOV r0, 0 // Disable BASEPRI masking (enable interrupts) + MOV r0, #0 // Disable BASEPRI masking (enable interrupts) MSR BASEPRI, r0 #else CPSIE i // Enable interrupts @@ -278,9 +279,19 @@ __tx_ts_wait: #endif #ifdef TX_ENABLE_WFI +#ifdef TX_PORT_USE_BASEPRI + CPSID i // Mask every interrupt with PRIMASK, which WFI ignores + MOV r1, #0 // Clear BASEPRI so that an interrupt masked by it + MSR BASEPRI, r1 // is still able to wake the processor +#endif DSB // Ensure no outstanding memory transactions WFI // Wait for interrupt ISB // Ensure pipeline is flushed +#ifdef TX_PORT_USE_BASEPRI + LDR r1, =TX_PORT_BASEPRI // Restore the BASEPRI mask + MSR BASEPRI, r1 + CPSIE i // Clear PRIMASK; a pending interrupt is taken here +#endif #endif #ifdef TX_LOW_POWER diff --git a/ports_arch/ARMv8-M/threadx/ac6/src/tx_thread_system_return.S b/ports_arch/ARMv8-M/threadx/ac6/src/tx_thread_system_return.S index e31c4a55..c188969c 100644 --- a/ports_arch/ARMv8-M/threadx/ac6/src/tx_thread_system_return.S +++ b/ports_arch/ARMv8-M/threadx/ac6/src/tx_thread_system_return.S @@ -9,6 +9,8 @@ * SPDX-License-Identifier: MIT **************************************************************************/ +// Portions of this file were generated with AI assistance. + /**************************************************************************/ /**************************************************************************/ @@ -74,6 +76,8 @@ _tx_thread_system_return: MOV r0, #0x10000000 // Load PENDSVSET bit MOV r1, #0xE000E000 // Load NVIC base STR r0, [r1, #0xD04] // Set PENDSVBIT in ICSR + DSB #0xF // Ensure memory access is complete + ISB #0xF // Flush pipeline MRS r0, IPSR // Pickup IPSR CMP r0, #0 // Is it a thread returning? BNE _isr_context // If ISR, skip interrupt enable @@ -82,10 +86,12 @@ _tx_thread_system_return: MOV r0, #0 MSR BASEPRI, r0 // Enable interrupts MSR BASEPRI, r1 // Restore original interrupt posture + ISB #0xF // Flush pipeline #else MRS r1, PRIMASK // Thread context returning, pickup PRIMASK CPSIE i // Enable interrupts MSR PRIMASK, r1 // Restore original interrupt posture + ISB #0xF // Flush pipeline #endif _isr_context: BX lr // Return to caller diff --git a/ports_arch/ARMv8-M/threadx/gnu/CMakeLists.txt b/ports_arch/ARMv8-M/threadx/gnu/CMakeLists.txt index 5ad3b8e7..a8e45b82 100644 --- a/ports_arch/ARMv8-M/threadx/gnu/CMakeLists.txt +++ b/ports_arch/ARMv8-M/threadx/gnu/CMakeLists.txt @@ -1,7 +1,8 @@ -target_sources(${PROJECT_NAME} PRIVATE +target_sources(${PROJECT_NAME} + PRIVATE + # {{BEGIN_TARGET_SOURCES}} ${CMAKE_CURRENT_LIST_DIR}/src/txe_thread_secure_stack_allocate.c ${CMAKE_CURRENT_LIST_DIR}/src/txe_thread_secure_stack_free.c - ${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 @@ -14,8 +15,11 @@ target_sources(${PROJECT_NAME} PRIVATE ${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} PUBLIC - inc +target_include_directories(${PROJECT_NAME} + SYSTEM + PUBLIC + ${CMAKE_CURRENT_LIST_DIR}/inc ) diff --git a/ports_arch/ARMv8-M/threadx/gnu/readme_threadx.txt b/ports_arch/ARMv8-M/threadx/gnu/readme_threadx.txt index 2cce95a4..907d6335 100644 --- a/ports_arch/ARMv8-M/threadx/gnu/readme_threadx.txt +++ b/ports_arch/ARMv8-M/threadx/gnu/readme_threadx.txt @@ -200,7 +200,12 @@ information associated with this specific port of ThreadX: 03-02-2021 The following files were changed/added for version 6.1.5: tx_port.h Added ULONG64_DEFINED -09-30-2020 Initial ThreadX 6.1 version for Cortex-Mxx using GNU tools. +09-30-2020 Initial ThreadX 6.1 version of this Armv8-M port using GNU tools. + + The dates above belong to this shared port, which every Armv8-M + core is generated from. They are not the date a particular core + gained a ThreadX port: that is when its name was added to + scripts/copy_armv8_m.sh. Copyright(c) 1996-2020 Microsoft Corporation diff --git a/ports_arch/ARMv8-M/threadx/gnu/src/tx_initialize_low_level.S b/ports_arch/ARMv8-M/threadx/gnu/src/tx_initialize_low_level.S deleted file mode 100644 index 842dcdf4..00000000 --- a/ports_arch/ARMv8-M/threadx/gnu/src/tx_initialize_low_level.S +++ /dev/null @@ -1,273 +0,0 @@ -/*************************************************************************** - * 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 - * https://opensource.org/licenses/MIT. - * - * SPDX-License-Identifier: MIT - **************************************************************************/ - - -/**************************************************************************/ -/**************************************************************************/ -/** */ -/** ThreadX Component */ -/** */ -/** Initialize */ -/** */ -/**************************************************************************/ -/**************************************************************************/ - -#ifdef TX_INCLUDE_USER_DEFINE_FILE -#include "tx_user.h" -#endif - -SYSTEM_CLOCK = 6000000 -SYSTICK_CYCLES = ((SYSTEM_CLOCK / 100) -1) - -/* Setup the stack and heap areas. */ - -STACK_SIZE = 0x00000400 -HEAP_SIZE = 0x00000000 - -/**************************************************************************/ -/* */ -/* FUNCTION RELEASE */ -/* */ -/* _tx_initialize_low_level Cortex-Mxx/GNU */ -/* 6.2.1 */ -/* AUTHOR */ -/* */ -/* Scott Larson, Microsoft Corporation */ -/* */ -/* DESCRIPTION */ -/* */ -/* This function is responsible for any low-level processor */ -/* initialization, including setting up interrupt vectors, setting */ -/* up a periodic timer interrupt source, saving the system stack */ -/* pointer for use in ISR processing later, and finding the first */ -/* available RAM memory address for tx_application_define. */ -/* */ -/* INPUT */ -/* */ -/* None */ -/* */ -/* OUTPUT */ -/* */ -/* None */ -/* */ -/* CALLS */ -/* */ -/* None */ -/* */ -/* CALLED BY */ -/* */ -/* _tx_initialize_kernel_enter ThreadX entry function */ -/* */ -/**************************************************************************/ -// VOID _tx_initialize_low_level(VOID) -// { - .section .text - .balign 4 - .syntax unified - .eabi_attribute Tag_ABI_align_preserved, 1 - .global _tx_initialize_low_level - .thumb_func -.type _tx_initialize_low_level, function -_tx_initialize_low_level: - - /* Disable interrupts during ThreadX initialization. */ - CPSID i - - /* Set base of available memory to end of non-initialised RAM area. */ - LDR r0, =_tx_initialize_unused_memory // Build address of unused memory pointer - LDR r1, =__RAM_segment_used_end__ // Build first free address - ADD r1, r1, #4 // - STR r1, [r0] // Setup first unused memory pointer - - /* Setup Vector Table Offset Register. */ - MOV r0, #0xE000E000 // Build address of NVIC registers - LDR r1, =_vectors // Pickup address of vector table - STR r1, [r0, #0xD08] // Set vector table address - - /* Enable the cycle count register. */ - LDR r0, =0xE0001000 // Build address of DWT register - LDR r1, [r0] // Pickup the current value - ORR r1, r1, #1 // Set the CYCCNTENA bit - STR r1, [r0] // Enable the cycle count register - - /* Set system stack pointer from vector value. */ - LDR r0, =_tx_thread_system_stack_ptr // Build address of system stack pointer - LDR r1, =_vectors // Pickup address of vector table - LDR r1, [r1] // Pickup reset stack pointer - STR r1, [r0] // Save system stack pointer - - /* Configure SysTick. */ - MOV r0, #0xE000E000 // Build address of NVIC registers - LDR r1, =SYSTICK_CYCLES - STR r1, [r0, #0x14] // Setup SysTick Reload Value - MOV r1, #0x7 // Build SysTick Control Enable Value - STR r1, [r0, #0x10] // Setup SysTick Control - - /* Configure handler priorities. */ - LDR r1, =0x00000000 // Rsrv, UsgF, BusF, MemM - STR r1, [r0, #0xD18] // Setup System Handlers 4-7 Priority Registers - LDR r1, =0xFF000000 // SVCl, Rsrv, Rsrv, Rsrv - STR r1, [r0, #0xD1C] // Setup System Handlers 8-11 Priority Registers - // Note: SVC must be lowest priority, which is 0xFF - LDR r1, =0x40FF0000 // SysT, PnSV, Rsrv, DbgM - STR r1, [r0, #0xD20] // Setup System Handlers 12-15 Priority Registers - // Note: PnSV must be lowest priority, which is 0xFF - - /* Return to caller. */ - BX lr -// } - - -/* Define shells for each of the unused vectors. */ - .section .text - .balign 4 - .syntax unified - .eabi_attribute Tag_ABI_align_preserved, 1 - .global __tx_BadHandler - .thumb_func -.type __tx_BadHandler, function -__tx_BadHandler: - B __tx_BadHandler - - - .section .text - .balign 4 - .syntax unified - .eabi_attribute Tag_ABI_align_preserved, 1 - .global __tx_IntHandler - .thumb_func -.type __tx_IntHandler, function -__tx_IntHandler: -// VOID InterruptHandler (VOID) -// { - PUSH {r0,lr} // Save LR (and dummy r0 to maintain stack alignment) -#if (defined(TX_ENABLE_EXECUTION_CHANGE_NOTIFY) || defined(TX_EXECUTION_PROFILE_ENABLE)) - BL _tx_execution_isr_enter // Call the ISR enter function -#endif - /* Do interrupt handler work here */ - /* .... */ -#if (defined(TX_ENABLE_EXECUTION_CHANGE_NOTIFY) || defined(TX_EXECUTION_PROFILE_ENABLE)) - BL _tx_execution_isr_exit // Call the ISR exit function -#endif - POP {r0,lr} - BX lr -// } - - - .section .text - .balign 4 - .syntax unified - .eabi_attribute Tag_ABI_align_preserved, 1 - .global SysTick_Handler - .thumb_func -.type SysTick_Handler, function -SysTick_Handler: -// VOID TimerInterruptHandler (VOID) -// { - PUSH {r0,lr} // Save LR (and dummy r0 to maintain stack alignment) -#if (defined(TX_ENABLE_EXECUTION_CHANGE_NOTIFY) || defined(TX_EXECUTION_PROFILE_ENABLE)) - BL _tx_execution_isr_enter // Call the ISR enter function -#endif - BL _tx_timer_interrupt -#if (defined(TX_ENABLE_EXECUTION_CHANGE_NOTIFY) || defined(TX_EXECUTION_PROFILE_ENABLE)) - BL _tx_execution_isr_exit // Call the ISR exit function -#endif - POP {r0,lr} - BX lr -// } - - - .section .text - .balign 4 - .syntax unified - .eabi_attribute Tag_ABI_align_preserved, 1 - .global HardFault_Handler - .thumb_func -.type HardFault_Handler, function -HardFault_Handler: - B HardFault_Handler - - - .section .text - .balign 4 - .syntax unified - .eabi_attribute Tag_ABI_align_preserved, 1 - .global UsageFault_Handler - .thumb_func -.type UsageFault_Handler, function -UsageFault_Handler: - CPSID i // Disable interrupts - // Check for stack limit fault - LDR r0, =0xE000ED28 // CFSR address - LDR r1,[r0] // Pick up CFSR - TST r1, #0x00100000 // Check for Stack Overflow -_unhandled_usage_loop: - BEQ _unhandled_usage_loop // If not stack overflow then loop - - // Handle stack overflow - STR r1, [r0] // Clear CFSR flag(s) - -#ifdef __ARM_FP - LDR r0, =0xE000EF34 // Cleanup FPU context: Load FPCCR address - LDR r1, [r0] // Load FPCCR - BIC r1, r1, #1 // Clear the lazy preservation active bit - STR r1, [r0] // Store the value -#endif - - LDR r0, =_tx_thread_current_ptr // Build current thread pointer address - LDR r0,[r0] // Pick up current thread pointer - PUSH {r0,lr} // Save LR (and r0 to maintain stack alignment) - BL _tx_thread_stack_error_handler // Call ThreadX/user handler - POP {r0,lr} // Restore LR and dummy reg - -#if (defined(TX_ENABLE_EXECUTION_CHANGE_NOTIFY) || defined(TX_EXECUTION_PROFILE_ENABLE)) - // Call the thread exit function to indicate the thread is no longer executing. - PUSH {r0, lr} // Save LR (and r0 just for alignment) - BL _tx_execution_thread_exit // Call the thread exit function - POP {r0, lr} // Recover LR -#endif - - MOV r1, #0 // Build NULL value - LDR r0, =_tx_thread_current_ptr // Pickup address of current thread pointer - STR r1, [r0] // Clear current thread pointer - - // Return from UsageFault_Handler exception - LDR r0, =0xE000ED04 // Load ICSR - LDR r1, =0x10000000 // Set PENDSVSET bit - STR r1, [r0] // Store ICSR - DSB // Wait for memory access to complete - CPSIE i // Enable interrupts - BX lr // Return from exception - - - - .section .text - .balign 4 - .syntax unified - .eabi_attribute Tag_ABI_align_preserved, 1 - .global __tx_NMIHandler - .thumb_func -.type __tx_NMIHandler, function -__tx_NMIHandler: - B __tx_NMIHandler - - - .section .text - .balign 4 - .syntax unified - .eabi_attribute Tag_ABI_align_preserved, 1 - .global __tx_DBGHandler - .thumb_func -.type __tx_DBGHandler, function -__tx_DBGHandler: - B __tx_DBGHandler - - .end diff --git a/ports_arch/ARMv8-M/threadx/gnu/src/tx_thread_schedule.S b/ports_arch/ARMv8-M/threadx/gnu/src/tx_thread_schedule.S index 0a30ab36..28548246 100644 --- a/ports_arch/ARMv8-M/threadx/gnu/src/tx_thread_schedule.S +++ b/ports_arch/ARMv8-M/threadx/gnu/src/tx_thread_schedule.S @@ -8,6 +8,7 @@ * * SPDX-License-Identifier: MIT **************************************************************************/ +// Portions of this file were generated with AI assistance. /**************************************************************************/ @@ -125,7 +126,7 @@ __tx_ts_handler: BL _tx_execution_thread_exit // Call the thread exit function POP {r0, lr} // Recover LR #ifdef TX_PORT_USE_BASEPRI - MOV r0, 0 // Disable BASEPRI masking (enable interrupts) + MOV r0, #0 // Disable BASEPRI masking (enable interrupts) MSR BASEPRI, r0 #else CPSIE i // Enable interrupts @@ -274,9 +275,19 @@ __tx_ts_wait: #endif #ifdef TX_ENABLE_WFI +#ifdef TX_PORT_USE_BASEPRI + CPSID i // Mask every interrupt with PRIMASK, which WFI ignores + MOV r1, #0 // Clear BASEPRI so that an interrupt masked by it + MSR BASEPRI, r1 // is still able to wake the processor +#endif DSB // Ensure no outstanding memory transactions WFI // Wait for interrupt ISB // Ensure pipeline is flushed +#ifdef TX_PORT_USE_BASEPRI + LDR r1, =TX_PORT_BASEPRI // Restore the BASEPRI mask + MSR BASEPRI, r1 + CPSIE i // Clear PRIMASK; a pending interrupt is taken here +#endif #endif #ifdef TX_LOW_POWER diff --git a/ports_arch/ARMv8-M/threadx/gnu/src/tx_thread_system_return.S b/ports_arch/ARMv8-M/threadx/gnu/src/tx_thread_system_return.S index 1e84582e..433b16ad 100644 --- a/ports_arch/ARMv8-M/threadx/gnu/src/tx_thread_system_return.S +++ b/ports_arch/ARMv8-M/threadx/gnu/src/tx_thread_system_return.S @@ -9,6 +9,8 @@ * SPDX-License-Identifier: MIT **************************************************************************/ +// Portions of this file were generated with AI assistance. + /**************************************************************************/ /**************************************************************************/ @@ -74,6 +76,8 @@ _tx_thread_system_return: MOV r0, #0x10000000 // Load PENDSVSET bit MOV r1, #0xE000E000 // Load NVIC base STR r0, [r1, #0xD04] // Set PENDSVBIT in ICSR + DSB #0xF // Ensure memory access is complete + ISB #0xF // Flush pipeline MRS r0, IPSR // Pickup IPSR CMP r0, #0 // Is it a thread returning? BNE _isr_context // If ISR, skip interrupt enable @@ -82,10 +86,12 @@ _tx_thread_system_return: MOV r0, #0 MSR BASEPRI, r0 // Enable interrupts MSR BASEPRI, r1 // Restore original interrupt posture + ISB #0xF // Flush pipeline #else MRS r1, PRIMASK // Thread context returning, pickup PRIMASK CPSIE i // Enable interrupts MSR PRIMASK, r1 // Restore original interrupt posture + ISB #0xF // Flush pipeline #endif _isr_context: BX lr // Return to caller diff --git a/ports_arch/ARMv8-M/threadx/iar/readme_threadx.txt b/ports_arch/ARMv8-M/threadx/iar/readme_threadx.txt index e0f46665..0cd743bd 100644 --- a/ports_arch/ARMv8-M/threadx/iar/readme_threadx.txt +++ b/ports_arch/ARMv8-M/threadx/iar/readme_threadx.txt @@ -211,7 +211,12 @@ information associated with this specific port of ThreadX: 03-02-2021 The following files were changed/added for version 6.1.5: tx_port.h Added ULONG64_DEFINED -09-30-2020 Initial ThreadX 6.1 version for Cortex-Mxx using IAR's ARM tools. +09-30-2020 Initial ThreadX 6.1 version of this Armv8-M port using IAR's ARM tools. + + The dates above belong to this shared port, which every Armv8-M + core is generated from. They are not the date a particular core + gained a ThreadX port: that is when its name was added to + scripts/copy_armv8_m.sh. Copyright(c) 1996-2020 Microsoft Corporation diff --git a/ports_arch/ARMv8-M/threadx/iar/src/tx_iar.c b/ports_arch/ARMv8-M/threadx/iar/src/tx_iar.c index 238b485e..ab6c209c 100644 --- a/ports_arch/ARMv8-M/threadx/iar/src/tx_iar.c +++ b/ports_arch/ARMv8-M/threadx/iar/src/tx_iar.c @@ -9,6 +9,7 @@ * SPDX-License-Identifier: MIT **************************************************************************/ +// Portions of this file were generated with AI assistance. /**************************************************************************/ /**************************************************************************/ @@ -270,7 +271,7 @@ TX_MUTEX *mutex_ptr; mutex_ptr = &__tx_iar_file_lock_mutexes[__tx_iar_file_lock_next_free_mutex++]; /* Check for wrap-around on the next free mutex. */ - if (__tx_iar_file_lock_next_free_mutex >= _MAX_LOCK) + if (__tx_iar_file_lock_next_free_mutex >= _MAX_FLOCK) { /* Yes, set the free index back to 0. */ @@ -287,7 +288,7 @@ TX_MUTEX *mutex_ptr; } /* Determine if a free mutex was found. */ - if (i >= _MAX_LOCK) + if (i >= _MAX_FLOCK) { /* Error! No more free mutexes! */ @@ -678,7 +679,7 @@ TX_MUTEX *mutex_ptr; mutex_ptr = &__tx_iar_file_lock_mutexes[__tx_iar_file_lock_next_free_mutex++]; /* Check for wrap-around on the next free mutex. */ - if (__tx_iar_file_lock_next_free_mutex >= _MAX_LOCK) + if (__tx_iar_file_lock_next_free_mutex >= _MAX_FLOCK) { /* Yes, set the free index back to 0. */ @@ -695,7 +696,7 @@ TX_MUTEX *mutex_ptr; } /* Determine if a free mutex was found. */ - if (i >= _MAX_LOCK) + if (i >= _MAX_FLOCK) { /* Error! No more free mutexes! */ diff --git a/ports_arch/ARMv8-M/threadx/iar/src/tx_initialize_low_level.s b/ports_arch/ARMv8-M/threadx/iar/src/tx_initialize_low_level.s index 6d8e07e8..9802be78 100644 --- a/ports_arch/ARMv8-M/threadx/iar/src/tx_initialize_low_level.s +++ b/ports_arch/ARMv8-M/threadx/iar/src/tx_initialize_low_level.s @@ -8,6 +8,7 @@ * * SPDX-License-Identifier: MIT **************************************************************************/ +// Portions of this file were generated with AI assistance. /**************************************************************************/ @@ -24,11 +25,9 @@ #include "tx_user.h" #endif - EXTERN _tx_thread_system_stack_ptr EXTERN _tx_initialize_unused_memory EXTERN _tx_timer_interrupt EXTERN __main - EXTERN __vector_table EXTERN _tx_thread_current_ptr EXTERN _tx_thread_stack_error_handler @@ -89,25 +88,17 @@ _tx_initialize_low_level: LDR r1, =__tx_free_memory_start // Build first free address STR r1, [r0] // Setup first unused memory pointer - /* Setup Vector Table Offset Register. */ - MOV r0, #0xE000E000 // Build address of NVIC registers - LDR r1, =__vector_table // Pickup address of vector table - STR r1, [r0, #0xD08] // Set vector table address - /* Enable the cycle count register. */ // LDR r0, =0xE0001000 // Build address of DWT register // LDR r1, [r0] // Pickup the current value // ORR r1, r1, #1 // Set the CYCCNTENA bit // STR r1, [r0] // Enable the cycle count register - /* Set system stack pointer from vector value. */ - LDR r0, =_tx_thread_system_stack_ptr // Build address of system stack pointer - LDR r1, =__vector_table // Pickup address of vector table - LDR r1, [r1] // Pickup reset stack pointer - STR r1, [r0] // Save system stack pointer - /* Configure SysTick. */ MOV r0, #0xE000E000 // Build address of NVIC registers + MOV r1, #0 // Build value for SysTick reset + STR r1, [r0, #0x10] // Reset SysTick Control + STR r1, [r0, #0x18] // Reset SysTick Counter Value LDR r1, =SYSTICK_CYCLES STR r1, [r0, #0x14] // Setup SysTick Reload Value MOV r1, #0x7 // Build SysTick Control Enable Value diff --git a/ports_arch/ARMv8-M/threadx/iar/src/tx_thread_schedule.s b/ports_arch/ARMv8-M/threadx/iar/src/tx_thread_schedule.s index 84f2043f..4fa3a10e 100644 --- a/ports_arch/ARMv8-M/threadx/iar/src/tx_thread_schedule.s +++ b/ports_arch/ARMv8-M/threadx/iar/src/tx_thread_schedule.s @@ -9,6 +9,8 @@ * SPDX-License-Identifier: MIT **************************************************************************/ +// Portions of this file were generated with AI assistance. + /**************************************************************************/ /**************************************************************************/ @@ -129,7 +131,7 @@ __tx_ts_handler: BL _tx_execution_thread_exit // Call the thread exit function POP {r0, lr} // Recover LR #ifdef TX_PORT_USE_BASEPRI - MOV r0, 0 // Disable BASEPRI masking (enable interrupts) + MOV r0, #0 // Disable BASEPRI masking (enable interrupts) MSR BASEPRI, r0 #else CPSIE i // Enable interrupts @@ -278,9 +280,19 @@ __tx_ts_wait: #endif #ifdef TX_ENABLE_WFI +#ifdef TX_PORT_USE_BASEPRI + CPSID i // Mask every interrupt with PRIMASK, which WFI ignores + MOV r1, #0 // Clear BASEPRI so that an interrupt masked by it + MSR BASEPRI, r1 // is still able to wake the processor +#endif DSB // Ensure no outstanding memory transactions WFI // Wait for interrupt ISB // Ensure pipeline is flushed +#ifdef TX_PORT_USE_BASEPRI + LDR r1, =TX_PORT_BASEPRI // Restore the BASEPRI mask + MSR BASEPRI, r1 + CPSIE i // Clear PRIMASK; a pending interrupt is taken here +#endif #endif #ifdef TX_LOW_POWER diff --git a/ports_arch/ARMv8-M/threadx/iar/src/tx_thread_system_return.s b/ports_arch/ARMv8-M/threadx/iar/src/tx_thread_system_return.s index f2a187ea..461d411a 100644 --- a/ports_arch/ARMv8-M/threadx/iar/src/tx_thread_system_return.s +++ b/ports_arch/ARMv8-M/threadx/iar/src/tx_thread_system_return.s @@ -1,16 +1,19 @@ -/*************************************************************************** - * 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 - * https://opensource.org/licenses/MIT. - * - * SPDX-License-Identifier: MIT - **************************************************************************/ +;*************************************************************************** +;* 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 +;* https://opensource.org/licenses/MIT. +;* +;* SPDX-License-Identifier: MIT +;************************************************************************** +; Portions of this file were generated with AI assistance. + + +;************************************************************************** -/**************************************************************************/ /**************************************************************************/ /** */ /** ThreadX Component */ @@ -69,6 +72,8 @@ _tx_thread_system_return: MOV r0, #0x10000000 // Load PENDSVSET bit MOV r1, #0xE000E000 // Load NVIC base STR r0, [r1, #0xD04] // Set PENDSVBIT in ICSR + DSB SY // Ensure memory access is complete + ISB SY // Flush pipeline MRS r0, IPSR // Pickup IPSR CMP r0, #0 // Is it a thread returning? BNE _isr_context // If ISR, skip interrupt enable @@ -77,10 +82,12 @@ _tx_thread_system_return: MOV r0, #0 MSR BASEPRI, r0 // Enable interrupts MSR BASEPRI, r1 // Restore original interrupt posture + ISB SY // Flush pipeline #else MRS r1, PRIMASK // Thread context returning, pickup PRIMASK CPSIE i // Enable interrupts MSR PRIMASK, r1 // Restore original interrupt posture + ISB SY // Flush pipeline #endif _isr_context: BX lr // Return to caller diff --git a/ports_arch/ARMv8-M/threadx/inc/tx_port.h b/ports_arch/ARMv8-M/threadx/inc/tx_port.h index 316da65b..c59feb71 100644 --- a/ports_arch/ARMv8-M/threadx/inc/tx_port.h +++ b/ports_arch/ARMv8-M/threadx/inc/tx_port.h @@ -9,6 +9,8 @@ * SPDX-License-Identifier: MIT **************************************************************************/ +// Portions of this file were generated with AI assistance. + /**************************************************************************/ /**************************************************************************/ @@ -541,7 +543,7 @@ UINT posture; #ifdef TX_PORT_USE_BASEPRI __attribute__( ( always_inline ) ) static inline void __set_basepri_value(UINT basepri_value) { - __asm__ volatile ("MSR BASEPRI,%0 ": : "r" (basepri_value)); + __asm__ volatile ("MSR BASEPRI,%0 ": : "r" (basepri_value) : "memory"); } #else __attribute__( ( always_inline ) ) static inline void __enable_interrupts(void) @@ -554,6 +556,7 @@ __attribute__( ( always_inline ) ) static inline void __restore_interrupt(UINT i { #ifdef TX_PORT_USE_BASEPRI __set_basepri_value(int_posture); + __asm__ volatile ("" : : : "memory"); #else __asm__ volatile ("MSR PRIMASK,%0": : "r" (int_posture): "memory"); #endif @@ -579,6 +582,7 @@ UINT interrupt_save; /* Set PendSV to invoke ThreadX scheduler. */ *((volatile ULONG *) 0xE000ED04) = ((ULONG) 0x10000000); + __asm__ volatile ("dsb sy \n isb sy " : : : "memory"); if (_tx_ipsr_get() == 0) { interrupt_save = __get_interrupt_posture(); @@ -588,6 +592,7 @@ UINT interrupt_save; __enable_interrupts(); #endif __restore_interrupt(interrupt_save); + __asm__ volatile ("isb sy " : : : "memory"); } } @@ -613,7 +618,7 @@ VOID _tx_thread_interrupt_restore(UIN #ifdef TX_THREAD_INIT CHAR _tx_version_id[] = - "(c) 2024 Microsoft Corp. (c) 2026-present Eclipse ThreadX contributors. * ThreadX Cortex-Mxx Version 6.5.1.202602a *"; + "(c) 2024 Microsoft Corp. (c) 2026-present Eclipse ThreadX contributors. * ThreadX Cortex-Mxx Version 6.5.2.202603 *"; #else #ifdef TX_MISRA_ENABLE extern CHAR _tx_version_id[100]; |
