diff options
| author | Frédéric Desbiens <[email protected]> | 2026-04-29 09:10:57 -0400 |
|---|---|---|
| committer | GitHub <[email protected]> | 2026-04-29 09:10:57 -0400 |
| commit | 33efad3fee3414aef0d99e416361226b8568fd26 (patch) | |
| tree | 75e01b7d63dee7e65219462753c5ce6e5ca5450e | |
| parent | d5c75fd38f1e7dfc15772f1b122d541fe8ee540c (diff) | |
Fixed race condition and message loss in Cortex-M ports (#523)
* Fixed race condition and message loss in Cortex-M GNU, AC6, and IAR ports (#516)
- Added compiler memory barriers to BASEPRI management functions in tx_port.h.
- Added architectural barriers (DSB/ISB) to scheduler return paths in tx_port.h and tx_thread_system_return.S to prevent fall-through before context switch.
- These changes address spurious thread resumption and lost messages, especially when TX_NOT_INTERRUPTABLE is enabled.
- These changes ensure that pending interrupts (specifically PendSV) are recognised before subsequent instructions are executed, following Kairalite's feedback and ARM architectural guidelines.
Assisted-by: Gemini (Gemini 2.0 Flash)
-----
* Added a comment in common/tx_queue_cleanup to document why the NI path omits revalidation guards
- In `TX_NOT_INTERRUPTABLE` mode, the caller keeps interrupts disabled across the entire cleanup call, so the race window that makes the guards necessary in the interruptable path cannot occur. Add a comment explaining this, and noting that all paths that resume a suspended thread clear tx_thread_suspend_cleanup before calling
_tx_thread_system_ni_resume, making double-cleanup impossible.
This prevents future false-positive suggestions (e.g. from AI tools) to add redundant checks to the NI path.
Relates to: eclipse-threadx/threadx#516
Co-authored-by: Copilot <[email protected]>
43 files changed, 327 insertions, 127 deletions
diff --git a/common/src/tx_queue_cleanup.c b/common/src/tx_queue_cleanup.c index 05a423b3..90607183 100644 --- a/common/src/tx_queue_cleanup.c +++ b/common/src/tx_queue_cleanup.c @@ -109,6 +109,19 @@ TX_THREAD *previous_thread; { #else + /* TX_NOT_INTERRUPTABLE path: the revalidation guards present in the + interruptable path above (cleanup pointer, suspension sequence, NULL + queue pointer, queue ID, and suspended count checks) are intentionally + omitted here. Those guards exist to handle the race window that opens + when the interruptable path calls TX_RESTORE before invoking cleanup, + allowing another context to service or abort the suspension in between. + In TX_NOT_INTERRUPTABLE mode the caller keeps interrupts disabled across + the entire cleanup call, so that race window never exists. Additionally, + every path that resumes a suspended thread (tx_queue_send, tx_queue_receive, + tx_queue_flush, tx_queue_delete) clears tx_thread_suspend_cleanup before + calling _tx_thread_system_ni_resume, making a double-cleanup impossible + under the NI serialisation guarantee. */ + /* Setup pointer to queue control block. */ queue_ptr = TX_VOID_TO_QUEUE_POINTER_CONVERT(thread_ptr -> tx_thread_suspend_control_block); #endif diff --git a/ports/cortex_m0/gnu/inc/tx_port.h b/ports/cortex_m0/gnu/inc/tx_port.h index 9b315869..ddeff5c5 100644 --- a/ports/cortex_m0/gnu/inc/tx_port.h +++ b/ports/cortex_m0/gnu/inc/tx_port.h @@ -9,6 +9,8 @@ * SPDX-License-Identifier: MIT **************************************************************************/ +// Some portions generated by Gemini (Gemini 2.0 Flash). + /**************************************************************************/ /**************************************************************************/ @@ -322,11 +324,13 @@ unsigned int interrupt_save; /* Set PendSV to invoke ThreadX scheduler. */ *((volatile ULONG *) 0xE000ED04) = ((ULONG) 0x10000000); + __asm__ volatile ("dsb 0xF \n isb 0xF " : : : "memory"); if (__get_ipsr_value() == 0) { interrupt_save = __get_primask_value(); __enable_interrupts(); __restore_interrupts(interrupt_save); + __asm__ volatile ("isb 0xF " : : : "memory"); } } diff --git a/ports/cortex_m0/gnu/src/tx_thread_system_return.S b/ports/cortex_m0/gnu/src/tx_thread_system_return.S index d798994e..6019b299 100644 --- a/ports/cortex_m0/gnu/src/tx_thread_system_return.S +++ b/ports/cortex_m0/gnu/src/tx_thread_system_return.S @@ -5,11 +5,14 @@ @ * terms of the MIT License which is available at @ * https://opensource.org/licenses/MIT. @ * -@ * SPDX-License-Identifier: MIT -@ **************************************************************************/ -@ -@ -@/**************************************************************************/ +* SPDX-License-Identifier: MIT +**************************************************************************/ + +// Some portions generated by Gemini (Gemini 2.0 Flash). + + +/**************************************************************************/ + @/**************************************************************************/ @/** */ @/** ThreadX Component */ @@ -72,12 +75,15 @@ _tx_thread_system_return: LDR r0, =0x10000000 @ Load PENDSVSET bit LDR r1, =0xE000ED04 @ Load NVIC base STR r0, [r1] @ 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 MRS r1, PRIMASK @ Thread context returning, pickup PRIMASK CPSIE i @ Enable interrupts MSR PRIMASK, r1 @ Restore original interrupt posture + ISB #0xF @ Flush pipeline _isr_context: BX lr @ Return to caller @/* } */ diff --git a/ports/cortex_m0/iar/inc/tx_port.h b/ports/cortex_m0/iar/inc/tx_port.h index af5f58bb..c92c71f8 100644 --- a/ports/cortex_m0/iar/inc/tx_port.h +++ b/ports/cortex_m0/iar/inc/tx_port.h @@ -313,6 +313,7 @@ __istate_t interrupt_save; /* Set PendSV to invoke ThreadX scheduler. */ *((volatile ULONG *) 0xE000ED04) = ((ULONG) 0x10000000); + __asm__ volatile ("dsb 0xF \n isb 0xF " : : : "memory"); if (__get_IPSR() == 0) { interrupt_save = __get_interrupt_state(); diff --git a/ports/cortex_m0/iar/src/tx_thread_system_return.s b/ports/cortex_m0/iar/src/tx_thread_system_return.s index da8a481e..9426a137 100644 --- a/ports/cortex_m0/iar/src/tx_thread_system_return.s +++ b/ports/cortex_m0/iar/src/tx_thread_system_return.s @@ -1,5 +1,6 @@ -;/*************************************************************************** +;*************************************************************************** ; * Copyright (c) 2024 Microsoft Corporation +; * Copyright (c) 2026-present Eclipse ThreadX contributors ; * ; * This program and the accompanying materials are made available under the ; * terms of the MIT License which is available at @@ -7,6 +8,8 @@ ; * ; * SPDX-License-Identifier: MIT ; **************************************************************************/ + +; Some portions generated by Gemini (Gemini 2.0 Flash). ; ; ;/**************************************************************************/ @@ -68,6 +71,8 @@ _tx_thread_system_return: LDR r0, =0x10000000 ; Load PENDSVSET bit LDR r1, =0xE000ED04 ; Load NVIC base STR r0, [r1] ; 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 diff --git a/ports/cortex_m23/ac6/inc/tx_port.h b/ports/cortex_m23/ac6/inc/tx_port.h index 5ae0b62b..2140af53 100644 --- a/ports/cortex_m23/ac6/inc/tx_port.h +++ b/ports/cortex_m23/ac6/inc/tx_port.h @@ -9,6 +9,8 @@ * SPDX-License-Identifier: MIT **************************************************************************/ +// Some portions generated by Gemini (Gemini 2.0 Flash). + /**************************************************************************/ /**************************************************************************/ @@ -376,6 +378,7 @@ unsigned int was_masked; /* Set PendSV to invoke ThreadX scheduler. */ *((volatile ULONG *) 0xE000ED04) = ((ULONG) 0x10000000); + __asm__ volatile ("dsb 0xF \n isb 0xF " : : : "memory"); if (_get_ipsr() == 0) { was_masked = __disable_irq(); diff --git a/ports/cortex_m23/ac6/src/tx_thread_system_return.S b/ports/cortex_m23/ac6/src/tx_thread_system_return.S index d85981da..c0bfe023 100644 --- a/ports/cortex_m23/ac6/src/tx_thread_system_return.S +++ b/ports/cortex_m23/ac6/src/tx_thread_system_return.S @@ -9,6 +9,8 @@ * SPDX-License-Identifier: MIT **************************************************************************/ +// Some portions generated by Gemini (Gemini 2.0 Flash). + /**************************************************************************/ /**************************************************************************/ @@ -74,6 +76,8 @@ _tx_thread_system_return: LDR r0, =0x10000000 // Load PENDSVSET bit LDR r1, =0xE000ED04 // Load ICSR address STR r0, [r1] // 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 diff --git a/ports/cortex_m23/gnu/inc/tx_port.h b/ports/cortex_m23/gnu/inc/tx_port.h index b1eab9e3..b6681139 100644 --- a/ports/cortex_m23/gnu/inc/tx_port.h +++ b/ports/cortex_m23/gnu/inc/tx_port.h @@ -9,6 +9,8 @@ * SPDX-License-Identifier: MIT **************************************************************************/ +// Some portions generated by Gemini (Gemini 2.0 Flash). + /**************************************************************************/ /**************************************************************************/ @@ -389,11 +391,13 @@ unsigned int interrupt_save; /* Set PendSV to invoke ThreadX scheduler. */ *((volatile ULONG *) 0xE000ED04) = ((ULONG) 0x10000000); + __asm__ volatile ("dsb 0xF \n isb 0xF " : : : "memory"); if (_get_ipsr() == 0) { interrupt_save = __get_primask_value(); __enable_interrupts(); __restore_interrupts(interrupt_save); + __asm__ volatile ("isb 0xF " : : : "memory"); } } diff --git a/ports/cortex_m23/gnu/src/tx_thread_system_return.S b/ports/cortex_m23/gnu/src/tx_thread_system_return.S index a14fdba3..ca5408d7 100644 --- a/ports/cortex_m23/gnu/src/tx_thread_system_return.S +++ b/ports/cortex_m23/gnu/src/tx_thread_system_return.S @@ -9,6 +9,8 @@ * SPDX-License-Identifier: MIT **************************************************************************/ +// Some portions generated by Gemini (Gemini 2.0 Flash). + /**************************************************************************/ /**************************************************************************/ @@ -74,12 +76,15 @@ _tx_thread_system_return: LDR r0, =0x10000000 // Load PENDSVSET bit LDR r1, =0xE000ED04 // Load ICSR address STR r0, [r1] // 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 MRS r1, PRIMASK // Thread context returning, pickup PRIMASK CPSIE i // Enable interrupts MSR PRIMASK, r1 // Restore original interrupt posture + ISB #0xF // Flush pipeline _isr_context: BX lr // Return to caller // } diff --git a/ports/cortex_m23/iar/inc/tx_port.h b/ports/cortex_m23/iar/inc/tx_port.h index be6bebd5..dee22f50 100644 --- a/ports/cortex_m23/iar/inc/tx_port.h +++ b/ports/cortex_m23/iar/inc/tx_port.h @@ -399,6 +399,7 @@ __istate_t interrupt_save; /* Set PendSV to invoke ThreadX scheduler. */ *((volatile ULONG *) 0xE000ED04) = ((ULONG) 0x10000000); + __asm__ volatile ("dsb 0xF \n isb 0xF " : : : "memory"); if (__get_IPSR() == 0) { interrupt_save = __get_interrupt_state(); diff --git a/ports/cortex_m23/iar/src/tx_thread_system_return.s b/ports/cortex_m23/iar/src/tx_thread_system_return.s index 91ef52c7..da4b6d04 100644 --- a/ports/cortex_m23/iar/src/tx_thread_system_return.s +++ b/ports/cortex_m23/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 +;************************************************************************** +; Some portions generated by Gemini (Gemini 2.0 Flash). + + +;************************************************************************** -/**************************************************************************/ /**************************************************************************/ /** */ /** ThreadX Component */ @@ -65,6 +68,8 @@ _tx_thread_system_return: LDR r0, =0x10000000 // Load PENDSVSET bit LDR r1, =0xE000ED04 // Load ICSR address STR r0, [r1] // 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 diff --git a/ports/cortex_m3/ac6/inc/tx_port.h b/ports/cortex_m3/ac6/inc/tx_port.h index 0a25ae64..32604f3c 100644 --- a/ports/cortex_m3/ac6/inc/tx_port.h +++ b/ports/cortex_m3/ac6/inc/tx_port.h @@ -9,6 +9,8 @@ * SPDX-License-Identifier: MIT **************************************************************************/ +// Some portions generated by Gemini (Gemini 2.0 Flash). + /**************************************************************************/ /**************************************************************************/ @@ -539,20 +541,20 @@ 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 +#endif + __attribute__( ( always_inline ) ) static inline void __enable_interrupts(void) { __asm__ volatile ("CPSIE i": : : "memory"); } -#endif __attribute__( ( always_inline ) ) static inline void __restore_interrupt(unsigned int int_posture) { #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 +580,7 @@ unsigned int interrupt_save; /* Set PendSV to invoke ThreadX scheduler. */ *((volatile ULONG *) 0xE000ED04) = ((ULONG) 0x10000000); + __asm__ volatile ("dsb 0xF \n isb 0xF " : : : "memory"); if (__get_ipsr_value() == 0) { interrupt_save = __get_interrupt_posture(); @@ -589,7 +592,6 @@ unsigned int interrupt_save; __restore_interrupt(interrupt_save); } } - #define TX_INTERRUPT_SAVE_AREA UINT interrupt_save; #define TX_DISABLE interrupt_save = __disable_interrupts(); #define TX_RESTORE __restore_interrupt(interrupt_save); diff --git a/ports/cortex_m3/ac6/src/tx_thread_system_return.S b/ports/cortex_m3/ac6/src/tx_thread_system_return.S index e1c5c2a2..a8654f6b 100644 --- a/ports/cortex_m3/ac6/src/tx_thread_system_return.S +++ b/ports/cortex_m3/ac6/src/tx_thread_system_return.S @@ -9,6 +9,8 @@ * SPDX-License-Identifier: MIT **************************************************************************/ +// Some portions generated by Gemini (Gemini 2.0 Flash). + /**************************************************************************/ /**************************************************************************/ @@ -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 diff --git a/ports/cortex_m3/gnu/inc/tx_port.h b/ports/cortex_m3/gnu/inc/tx_port.h index 23affb8b..391688bd 100644 --- a/ports/cortex_m3/gnu/inc/tx_port.h +++ b/ports/cortex_m3/gnu/inc/tx_port.h @@ -9,6 +9,8 @@ * SPDX-License-Identifier: MIT **************************************************************************/ +// Some portions generated by Gemini (Gemini 2.0 Flash). + /**************************************************************************/ /**************************************************************************/ @@ -539,7 +541,7 @@ 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 +554,6 @@ __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"); #else __asm__ volatile ("MSR PRIMASK,%0": : "r" (int_posture): "memory"); #endif @@ -578,6 +579,7 @@ unsigned int interrupt_save; /* Set PendSV to invoke ThreadX scheduler. */ *((volatile ULONG *) 0xE000ED04) = ((ULONG) 0x10000000); + __asm__ volatile ("dsb 0xF \n isb 0xF " : : : "memory"); if (__get_ipsr_value() == 0) { interrupt_save = __get_interrupt_posture(); @@ -587,6 +589,7 @@ unsigned int interrupt_save; __enable_interrupts(); #endif __restore_interrupt(interrupt_save); + __asm__ volatile ("isb 0xF " : : : "memory"); } } diff --git a/ports/cortex_m3/gnu/src/tx_thread_system_return.S b/ports/cortex_m3/gnu/src/tx_thread_system_return.S index 9d9a32fc..92ad3f62 100644 --- a/ports/cortex_m3/gnu/src/tx_thread_system_return.S +++ b/ports/cortex_m3/gnu/src/tx_thread_system_return.S @@ -9,6 +9,8 @@ * SPDX-License-Identifier: MIT **************************************************************************/ +// Some portions generated by Gemini (Gemini 2.0 Flash). + /**************************************************************************/ /**************************************************************************/ @@ -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/cortex_m3/iar/inc/tx_port.h b/ports/cortex_m3/iar/inc/tx_port.h index ff8b75ca..1b298161 100644 --- a/ports/cortex_m3/iar/inc/tx_port.h +++ b/ports/cortex_m3/iar/inc/tx_port.h @@ -9,6 +9,8 @@ * SPDX-License-Identifier: MIT **************************************************************************/ +// Some portions generated by Gemini (Gemini 2.0 Flash). + /**************************************************************************/ /**************************************************************************/ @@ -539,20 +541,20 @@ 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 +#endif + __attribute__( ( always_inline ) ) static inline void __enable_interrupts(void) { __asm__ volatile ("CPSIE i": : : "memory"); } -#endif __attribute__( ( always_inline ) ) static inline void __restore_interrupt(unsigned int int_posture) { #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 +580,7 @@ unsigned int interrupt_save; /* Set PendSV to invoke ThreadX scheduler. */ *((volatile ULONG *) 0xE000ED04) = ((ULONG) 0x10000000); + __asm__ volatile ("dsb 0xF \n isb 0xF " : : : "memory"); if (__get_ipsr_value() == 0) { interrupt_save = __get_interrupt_posture(); @@ -589,7 +592,6 @@ unsigned int interrupt_save; __restore_interrupt(interrupt_save); } } - #define TX_INTERRUPT_SAVE_AREA UINT interrupt_save; #define TX_DISABLE interrupt_save = __disable_interrupts(); #define TX_RESTORE __restore_interrupt(interrupt_save); diff --git a/ports/cortex_m3/iar/src/tx_thread_system_return.s b/ports/cortex_m3/iar/src/tx_thread_system_return.s index 712a6e5c..8bd4ca82 100644 --- a/ports/cortex_m3/iar/src/tx_thread_system_return.s +++ b/ports/cortex_m3/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 +;************************************************************************** +; Some portions generated by Gemini (Gemini 2.0 Flash). + + +;************************************************************************** -/**************************************************************************/ /**************************************************************************/ /** */ /** 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 diff --git a/ports/cortex_m33/ac6/inc/tx_port.h b/ports/cortex_m33/ac6/inc/tx_port.h index e2a8f6e6..a706ff62 100644 --- a/ports/cortex_m33/ac6/inc/tx_port.h +++ b/ports/cortex_m33/ac6/inc/tx_port.h @@ -9,6 +9,8 @@ * SPDX-License-Identifier: MIT **************************************************************************/ +// Some portions generated by Gemini (Gemini 2.0 Flash). + /**************************************************************************/ /**************************************************************************/ @@ -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 0xF \n isb 0xF " : : : "memory"); if (_tx_ipsr_get() == 0) { interrupt_save = __get_interrupt_posture(); diff --git a/ports/cortex_m33/ac6/src/tx_thread_system_return.S b/ports/cortex_m33/ac6/src/tx_thread_system_return.S index 3c97b666..e57b28ea 100644 --- a/ports/cortex_m33/ac6/src/tx_thread_system_return.S +++ b/ports/cortex_m33/ac6/src/tx_thread_system_return.S @@ -9,6 +9,8 @@ * SPDX-License-Identifier: MIT **************************************************************************/ +// Some portions generated by Gemini (Gemini 2.0 Flash). + /**************************************************************************/ /**************************************************************************/ @@ -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 diff --git a/ports/cortex_m33/gnu/inc/tx_port.h b/ports/cortex_m33/gnu/inc/tx_port.h index 727e9fce..2b962069 100644 --- a/ports/cortex_m33/gnu/inc/tx_port.h +++ b/ports/cortex_m33/gnu/inc/tx_port.h @@ -9,6 +9,8 @@ * SPDX-License-Identifier: MIT **************************************************************************/ +// Some portions generated by Gemini (Gemini 2.0 Flash). + /**************************************************************************/ /**************************************************************************/ @@ -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) @@ -579,6 +581,7 @@ UINT interrupt_save; /* Set PendSV to invoke ThreadX scheduler. */ *((volatile ULONG *) 0xE000ED04) = ((ULONG) 0x10000000); + __asm__ volatile ("dsb 0xF \n isb 0xF " : : : "memory"); if (_tx_ipsr_get() == 0) { interrupt_save = __get_interrupt_posture(); @@ -588,6 +591,7 @@ UINT interrupt_save; __enable_interrupts(); #endif __restore_interrupt(interrupt_save); + __asm__ volatile ("isb 0xF " : : : "memory"); } } diff --git a/ports/cortex_m33/gnu/src/tx_thread_system_return.S b/ports/cortex_m33/gnu/src/tx_thread_system_return.S index 17db56a5..15609393 100644 --- a/ports/cortex_m33/gnu/src/tx_thread_system_return.S +++ b/ports/cortex_m33/gnu/src/tx_thread_system_return.S @@ -9,6 +9,8 @@ * SPDX-License-Identifier: MIT **************************************************************************/ +// Some portions generated by Gemini (Gemini 2.0 Flash). + /**************************************************************************/ /**************************************************************************/ @@ -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/cortex_m33/iar/inc/tx_port.h b/ports/cortex_m33/iar/inc/tx_port.h index 62f20620..6298ddcb 100644 --- a/ports/cortex_m33/iar/inc/tx_port.h +++ b/ports/cortex_m33/iar/inc/tx_port.h @@ -9,6 +9,8 @@ * SPDX-License-Identifier: MIT **************************************************************************/ +// Some portions generated by Gemini (Gemini 2.0 Flash). + /**************************************************************************/ /**************************************************************************/ @@ -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 0xF \n isb 0xF " : : : "memory"); if (_tx_ipsr_get() == 0) { interrupt_save = __get_interrupt_posture(); diff --git a/ports/cortex_m33/iar/src/tx_thread_system_return.s b/ports/cortex_m33/iar/src/tx_thread_system_return.s index 442e0e14..83eb4a66 100644 --- a/ports/cortex_m33/iar/src/tx_thread_system_return.s +++ b/ports/cortex_m33/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 +;************************************************************************** +; Some portions generated by Gemini (Gemini 2.0 Flash). + + +;************************************************************************** -/**************************************************************************/ /**************************************************************************/ /** */ /** 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 diff --git a/ports/cortex_m4/ac6/inc/tx_port.h b/ports/cortex_m4/ac6/inc/tx_port.h index fa109c52..c35bb424 100644 --- a/ports/cortex_m4/ac6/inc/tx_port.h +++ b/ports/cortex_m4/ac6/inc/tx_port.h @@ -9,6 +9,8 @@ * SPDX-License-Identifier: MIT **************************************************************************/ +// Some portions generated by Gemini (Gemini 2.0 Flash). + /**************************************************************************/ /**************************************************************************/ @@ -539,20 +541,20 @@ 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 +#endif + __attribute__( ( always_inline ) ) static inline void __enable_interrupts(void) { __asm__ volatile ("CPSIE i": : : "memory"); } -#endif __attribute__( ( always_inline ) ) static inline void __restore_interrupt(unsigned int int_posture) { #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 +580,22 @@ unsigned int interrupt_save; /* Set PendSV to invoke ThreadX scheduler. */ *((volatile ULONG *) 0xE000ED04) = ((ULONG) 0x10000000); + __asm__ volatile ("dsb 0xF \n isb 0xF " : : : "memory"); + if (__get_ipsr_value() == 0) + { + interrupt_save = __get_interrupt_posture(); +#ifdef TX_PORT_USE_BASEPRI + __set_basepri_value(0); +#else + __enable_interrupts(); +#endif + __restore_interrupt(interrupt_save); + } +} +unsigned int interrupt_save; + + /* Set PendSV to invoke ThreadX scheduler. */ + *((volatile ULONG *) 0xE000ED04) = ((ULONG) 0x10000000); if (__get_ipsr_value() == 0) { interrupt_save = __get_interrupt_posture(); diff --git a/ports/cortex_m4/ac6/src/tx_thread_system_return.S b/ports/cortex_m4/ac6/src/tx_thread_system_return.S index b4348f9d..4c5068ee 100644 --- a/ports/cortex_m4/ac6/src/tx_thread_system_return.S +++ b/ports/cortex_m4/ac6/src/tx_thread_system_return.S @@ -9,6 +9,8 @@ * SPDX-License-Identifier: MIT **************************************************************************/ +// Some portions generated by Gemini (Gemini 2.0 Flash). + /**************************************************************************/ /**************************************************************************/ @@ -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 diff --git a/ports/cortex_m4/gnu/inc/tx_port.h b/ports/cortex_m4/gnu/inc/tx_port.h index 7c2b04c5..a415dfbe 100644 --- a/ports/cortex_m4/gnu/inc/tx_port.h +++ b/ports/cortex_m4/gnu/inc/tx_port.h @@ -9,6 +9,8 @@ * SPDX-License-Identifier: MIT **************************************************************************/ +// Some portions generated by Gemini (Gemini 2.0 Flash). + /**************************************************************************/ /**************************************************************************/ @@ -539,9 +541,10 @@ 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 +#endif + __attribute__( ( always_inline ) ) static inline void __enable_interrupts(void) { __asm__ volatile ("CPSIE i": : : "memory"); @@ -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 0xF \n isb 0xF " : : : "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 0xF " : : : "memory"); } } diff --git a/ports/cortex_m4/gnu/src/tx_thread_system_return.S b/ports/cortex_m4/gnu/src/tx_thread_system_return.S index 8c4a09fd..4709af37 100644 --- a/ports/cortex_m4/gnu/src/tx_thread_system_return.S +++ b/ports/cortex_m4/gnu/src/tx_thread_system_return.S @@ -9,6 +9,8 @@ * SPDX-License-Identifier: MIT **************************************************************************/ +// Some portions generated by Gemini (Gemini 2.0 Flash). + /**************************************************************************/ /**************************************************************************/ @@ -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/cortex_m4/iar/inc/tx_port.h b/ports/cortex_m4/iar/inc/tx_port.h index 1253befa..85fe8e6e 100644 --- a/ports/cortex_m4/iar/inc/tx_port.h +++ b/ports/cortex_m4/iar/inc/tx_port.h @@ -9,6 +9,8 @@ * SPDX-License-Identifier: MIT **************************************************************************/ +// Some portions generated by Gemini (Gemini 2.0 Flash). + /**************************************************************************/ /**************************************************************************/ @@ -539,20 +541,20 @@ 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 +#endif + __attribute__( ( always_inline ) ) static inline void __enable_interrupts(void) { __asm__ volatile ("CPSIE i": : : "memory"); } -#endif __attribute__( ( always_inline ) ) static inline void __restore_interrupt(unsigned int int_posture) { #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 +580,7 @@ unsigned int interrupt_save; /* Set PendSV to invoke ThreadX scheduler. */ *((volatile ULONG *) 0xE000ED04) = ((ULONG) 0x10000000); + __asm__ volatile ("dsb 0xF \n isb 0xF " : : : "memory"); if (__get_ipsr_value() == 0) { interrupt_save = __get_interrupt_posture(); @@ -589,7 +592,6 @@ unsigned int interrupt_save; __restore_interrupt(interrupt_save); } } - #define TX_INTERRUPT_SAVE_AREA UINT interrupt_save; #define TX_DISABLE interrupt_save = __disable_interrupts(); #define TX_RESTORE __restore_interrupt(interrupt_save); diff --git a/ports/cortex_m4/iar/src/tx_thread_system_return.s b/ports/cortex_m4/iar/src/tx_thread_system_return.s index 4f8b9870..f9a668d9 100644 --- a/ports/cortex_m4/iar/src/tx_thread_system_return.s +++ b/ports/cortex_m4/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 +;************************************************************************** +; Some portions generated by Gemini (Gemini 2.0 Flash). + + +;************************************************************************** -/**************************************************************************/ /**************************************************************************/ /** */ /** 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 diff --git a/ports/cortex_m55/gnu/inc/tx_port.h b/ports/cortex_m55/gnu/inc/tx_port.h index a70426fa..ff5b001a 100644 --- a/ports/cortex_m55/gnu/inc/tx_port.h +++ b/ports/cortex_m55/gnu/inc/tx_port.h @@ -9,6 +9,8 @@ * SPDX-License-Identifier: MIT **************************************************************************/ +// Some portions generated by Gemini (Gemini 2.0 Flash). + /**************************************************************************/ /**************************************************************************/ @@ -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 0xF \n isb 0xF " : : : "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 0xF " : : : "memory"); } } diff --git a/ports/cortex_m55/gnu/src/tx_thread_system_return.S b/ports/cortex_m55/gnu/src/tx_thread_system_return.S index 0fc717b9..f13f832a 100644 --- a/ports/cortex_m55/gnu/src/tx_thread_system_return.S +++ b/ports/cortex_m55/gnu/src/tx_thread_system_return.S @@ -9,6 +9,8 @@ * SPDX-License-Identifier: MIT **************************************************************************/ +// Some portions generated by Gemini (Gemini 2.0 Flash). + /**************************************************************************/ /**************************************************************************/ @@ -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/cortex_m55/iar/inc/tx_port.h b/ports/cortex_m55/iar/inc/tx_port.h index b8a389f5..c1b94ea0 100644 --- a/ports/cortex_m55/iar/inc/tx_port.h +++ b/ports/cortex_m55/iar/inc/tx_port.h @@ -579,6 +579,7 @@ UINT interrupt_save; /* Set PendSV to invoke ThreadX scheduler. */ *((volatile ULONG *) 0xE000ED04) = ((ULONG) 0x10000000); + __asm__ volatile ("dsb 0xF \n isb 0xF " : : : "memory"); if (_tx_ipsr_get() == 0) { interrupt_save = __get_interrupt_posture(); diff --git a/ports/cortex_m55/iar/src/tx_thread_system_return.s b/ports/cortex_m55/iar/src/tx_thread_system_return.s index 2762f49e..20493afc 100644 --- a/ports/cortex_m55/iar/src/tx_thread_system_return.s +++ b/ports/cortex_m55/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 +;************************************************************************** +; Some portions generated by Gemini (Gemini 2.0 Flash). + + +;************************************************************************** -/**************************************************************************/ /**************************************************************************/ /** */ /** 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 diff --git a/ports/cortex_m7/ac6/inc/tx_port.h b/ports/cortex_m7/ac6/inc/tx_port.h index d3b3bb01..d8c2b51e 100644 --- a/ports/cortex_m7/ac6/inc/tx_port.h +++ b/ports/cortex_m7/ac6/inc/tx_port.h @@ -9,6 +9,8 @@ * SPDX-License-Identifier: MIT **************************************************************************/ +// Some portions generated by Gemini (Gemini 2.0 Flash). + /**************************************************************************/ /**************************************************************************/ @@ -539,20 +541,20 @@ 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 +#endif + __attribute__( ( always_inline ) ) static inline void __enable_interrupts(void) { __asm__ volatile ("CPSIE i": : : "memory"); } -#endif __attribute__( ( always_inline ) ) static inline void __restore_interrupt(unsigned int int_posture) { #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 +580,7 @@ unsigned int interrupt_save; /* Set PendSV to invoke ThreadX scheduler. */ *((volatile ULONG *) 0xE000ED04) = ((ULONG) 0x10000000); + __asm__ volatile ("dsb 0xF \n isb 0xF " : : : "memory"); if (__get_ipsr_value() == 0) { interrupt_save = __get_interrupt_posture(); @@ -589,7 +592,6 @@ unsigned int interrupt_save; __restore_interrupt(interrupt_save); } } - #define TX_INTERRUPT_SAVE_AREA UINT interrupt_save; #define TX_DISABLE interrupt_save = __disable_interrupts(); #define TX_RESTORE __restore_interrupt(interrupt_save); diff --git a/ports/cortex_m7/ac6/src/tx_thread_system_return.S b/ports/cortex_m7/ac6/src/tx_thread_system_return.S index 831c00e4..a092e34c 100644 --- a/ports/cortex_m7/ac6/src/tx_thread_system_return.S +++ b/ports/cortex_m7/ac6/src/tx_thread_system_return.S @@ -9,6 +9,8 @@ * SPDX-License-Identifier: MIT **************************************************************************/ +// Some portions generated by Gemini (Gemini 2.0 Flash). + /**************************************************************************/ /**************************************************************************/ @@ -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 diff --git a/ports/cortex_m7/gnu/inc/tx_port.h b/ports/cortex_m7/gnu/inc/tx_port.h index 48a34cfa..77355aab 100644 --- a/ports/cortex_m7/gnu/inc/tx_port.h +++ b/ports/cortex_m7/gnu/inc/tx_port.h @@ -9,6 +9,8 @@ * SPDX-License-Identifier: MIT **************************************************************************/ +// Some portions generated by Gemini (Gemini 2.0 Flash). + /**************************************************************************/ /**************************************************************************/ @@ -539,25 +541,26 @@ 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 +#endif + __attribute__( ( always_inline ) ) static inline void __enable_interrupts(void) { __asm__ volatile ("CPSIE i": : : "memory"); } -#endif __attribute__( ( always_inline ) ) static inline void __restore_interrupt(unsigned int int_posture) { #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 } + __attribute__( ( always_inline ) ) static inline unsigned int __disable_interrupts(void) { unsigned int int_posture; @@ -578,6 +581,7 @@ unsigned int interrupt_save; /* Set PendSV to invoke ThreadX scheduler. */ *((volatile ULONG *) 0xE000ED04) = ((ULONG) 0x10000000); + __asm__ volatile ("dsb 0xF \n isb 0xF " : : : "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 0xF " : : : "memory"); } } diff --git a/ports/cortex_m7/gnu/src/tx_thread_system_return.S b/ports/cortex_m7/gnu/src/tx_thread_system_return.S index ce5a3f46..180894b3 100644 --- a/ports/cortex_m7/gnu/src/tx_thread_system_return.S +++ b/ports/cortex_m7/gnu/src/tx_thread_system_return.S @@ -9,6 +9,8 @@ * SPDX-License-Identifier: MIT **************************************************************************/ +// Some portions generated by Gemini (Gemini 2.0 Flash). + /**************************************************************************/ /**************************************************************************/ @@ -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/cortex_m7/iar/inc/tx_port.h b/ports/cortex_m7/iar/inc/tx_port.h index 63d821bf..14524c46 100644 --- a/ports/cortex_m7/iar/inc/tx_port.h +++ b/ports/cortex_m7/iar/inc/tx_port.h @@ -9,6 +9,8 @@ * SPDX-License-Identifier: MIT **************************************************************************/ +// Some portions generated by Gemini (Gemini 2.0 Flash). + /**************************************************************************/ /**************************************************************************/ @@ -539,20 +541,20 @@ 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 +#endif + __attribute__( ( always_inline ) ) static inline void __enable_interrupts(void) { __asm__ volatile ("CPSIE i": : : "memory"); } -#endif __attribute__( ( always_inline ) ) static inline void __restore_interrupt(unsigned int int_posture) { #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 +580,7 @@ unsigned int interrupt_save; /* Set PendSV to invoke ThreadX scheduler. */ *((volatile ULONG *) 0xE000ED04) = ((ULONG) 0x10000000); + __asm__ volatile ("dsb 0xF \n isb 0xF " : : : "memory"); if (__get_ipsr_value() == 0) { interrupt_save = __get_interrupt_posture(); @@ -589,7 +592,6 @@ unsigned int interrupt_save; __restore_interrupt(interrupt_save); } } - #define TX_INTERRUPT_SAVE_AREA UINT interrupt_save; #define TX_DISABLE interrupt_save = __disable_interrupts(); #define TX_RESTORE __restore_interrupt(interrupt_save); diff --git a/ports/cortex_m7/iar/src/tx_thread_system_return.s b/ports/cortex_m7/iar/src/tx_thread_system_return.s index 0cef80c6..00a07ea8 100644 --- a/ports/cortex_m7/iar/src/tx_thread_system_return.s +++ b/ports/cortex_m7/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 +;************************************************************************** +; Some portions generated by Gemini (Gemini 2.0 Flash). + + +;************************************************************************** -/**************************************************************************/ /**************************************************************************/ /** */ /** 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 diff --git a/ports/cortex_m85/gnu/inc/tx_port.h b/ports/cortex_m85/gnu/inc/tx_port.h index 9057a132..c1d2f731 100644 --- a/ports/cortex_m85/gnu/inc/tx_port.h +++ b/ports/cortex_m85/gnu/inc/tx_port.h @@ -9,6 +9,8 @@ * SPDX-License-Identifier: MIT **************************************************************************/ +// Some portions generated by Gemini (Gemini 2.0 Flash). + /**************************************************************************/ /**************************************************************************/ @@ -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 0xF \n isb 0xF " : : : "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 0xF " : : : "memory"); } } diff --git a/ports/cortex_m85/gnu/src/tx_thread_system_return.S b/ports/cortex_m85/gnu/src/tx_thread_system_return.S index bbb5a630..35630094 100644 --- a/ports/cortex_m85/gnu/src/tx_thread_system_return.S +++ b/ports/cortex_m85/gnu/src/tx_thread_system_return.S @@ -9,6 +9,8 @@ * SPDX-License-Identifier: MIT **************************************************************************/ +// Some portions generated by Gemini (Gemini 2.0 Flash). + /**************************************************************************/ /**************************************************************************/ @@ -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/cortex_m85/iar/inc/tx_port.h b/ports/cortex_m85/iar/inc/tx_port.h index bf245049..409aecdd 100644 --- a/ports/cortex_m85/iar/inc/tx_port.h +++ b/ports/cortex_m85/iar/inc/tx_port.h @@ -541,7 +541,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 +554,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 @@ -623,3 +624,5 @@ extern CHAR _tx_version_id[]; #endif #endif + +#endif diff --git a/ports/cortex_m85/iar/src/tx_thread_system_return.s b/ports/cortex_m85/iar/src/tx_thread_system_return.s index 768262a2..fcc87228 100644 --- a/ports/cortex_m85/iar/src/tx_thread_system_return.s +++ b/ports/cortex_m85/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 +;************************************************************************** +; Some portions generated by Gemini (Gemini 2.0 Flash). + + +;************************************************************************** -/**************************************************************************/ /**************************************************************************/ /** */ /** 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 |
