summaryrefslogtreecommitdiff
path: root/ports/cortex_r52/gnu/src
diff options
context:
space:
mode:
authorFrédéric Desbiens <[email protected]>2026-10-02 10:42:44 -0400
committerGitHub <[email protected]>2026-10-02 10:42:44 -0400
commit93387b0a60382a29579bbad5045c68328e3751df (patch)
tree42be790d602cb76f55090e5a7c418df7ea2b3428 /ports/cortex_r52/gnu/src
parent44d7c95c582d415c4ad84527180b29c93c3bf664 (diff)
parent28281cd5647d4671236ca08d19bd18ed15b2265a (diff)
Merge pull request #783 from eclipse-threadx/devv6.5.2.202603_rel
Merged changes ahead of the v6.5.2.202603 release
Diffstat (limited to 'ports/cortex_r52/gnu/src')
-rw-r--r--ports/cortex_r52/gnu/src/tx_port_offset_check.c86
-rw-r--r--ports/cortex_r52/gnu/src/tx_thread_context_restore.S247
-rw-r--r--ports/cortex_r52/gnu/src/tx_thread_context_save.S193
-rw-r--r--ports/cortex_r52/gnu/src/tx_thread_fiq_context_restore.S237
-rw-r--r--ports/cortex_r52/gnu/src/tx_thread_fiq_context_save.S195
-rw-r--r--ports/cortex_r52/gnu/src/tx_thread_fiq_nesting_end.S107
-rw-r--r--ports/cortex_r52/gnu/src/tx_thread_fiq_nesting_start.S99
-rw-r--r--ports/cortex_r52/gnu/src/tx_thread_interrupt_control.S108
-rw-r--r--ports/cortex_r52/gnu/src/tx_thread_interrupt_disable.S105
-rw-r--r--ports/cortex_r52/gnu/src/tx_thread_interrupt_restore.S96
-rw-r--r--ports/cortex_r52/gnu/src/tx_thread_irq_nesting_end.S106
-rw-r--r--ports/cortex_r52/gnu/src/tx_thread_irq_nesting_start.S99
-rw-r--r--ports/cortex_r52/gnu/src/tx_thread_schedule.S240
-rw-r--r--ports/cortex_r52/gnu/src/tx_thread_stack_build.S170
-rw-r--r--ports/cortex_r52/gnu/src/tx_thread_system_return.S169
-rw-r--r--ports/cortex_r52/gnu/src/tx_thread_vectored_context_save.S181
-rw-r--r--ports/cortex_r52/gnu/src/tx_timer_interrupt.S270
17 files changed, 2708 insertions, 0 deletions
diff --git a/ports/cortex_r52/gnu/src/tx_port_offset_check.c b/ports/cortex_r52/gnu/src/tx_port_offset_check.c
new file mode 100644
index 00000000..5e853fca
--- /dev/null
+++ b/ports/cortex_r52/gnu/src/tx_port_offset_check.c
@@ -0,0 +1,86 @@
+/***************************************************************************
+ * 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 */
+/** */
+/** Port Specific */
+/** */
+/**************************************************************************/
+/**************************************************************************/
+
+/**************************************************************************/
+/* */
+/* PORT SPECIFIC C INFORMATION RELEASE */
+/* */
+/* tx_port_offset_check.c Cortex-R52/GNU */
+/* 6.5.2 */
+/* AUTHOR */
+/* */
+/* Frédéric Desbiens, Eclipse Foundation */
+/* */
+/* DESCRIPTION */
+/* */
+/* Compile-time verification of the TX_THREAD structure offsets that */
+/* this port's assembly reaches by hard-coded displacement. The file */
+/* emits no code; it exists purely so that a layout change becomes a */
+/* build failure. */
+/* */
+/* Why this is needed: tx_thread_schedule.S, */
+/* tx_thread_system_return.S and tx_thread_context_restore.S read and */
+/* write the per-thread VFP enable flag as [thread, #144]. Nothing in */
+/* the toolchain connects that literal to the C structure, so adding a */
+/* member, enabling an option that adds one, or reordering the port */
+/* extensions would silently retarget those accesses at an unrelated */
+/* field -- corrupting thread state in a way that is extremely hard to */
+/* diagnose from the symptom. The offset was measured at 144 for the */
+/* default build and is asserted here. */
+/* */
+/* A negative array dimension is used rather than _Static_assert */
+/* because this project targets C99, where _Static_assert does not */
+/* exist. If an assertion below fails, the compiler reports a negative*/
+/* or zero-sized array for the named typedef. */
+/* */
+/**************************************************************************/
+
+#include "tx_api.h"
+#include <stddef.h>
+
+/* Offset of the VFP enable flag as encoded in this port's assembly.
+ Overridable only so that the assertion itself can be tested. */
+
+#ifndef TX_PORT_VFP_ENABLE_OFFSET
+#define TX_PORT_VFP_ENABLE_OFFSET 144
+#endif
+
+typedef char
+tx_port_assert_vfp_enable_offset_is_144[
+ (offsetof(TX_THREAD, tx_thread_vfp_enable) == TX_PORT_VFP_ENABLE_OFFSET)
+ ? 1 : -1];
+
+/* The stack pointer is read as [thread, #8] by tx_thread_schedule.S and
+ written by tx_thread_system_return.S, and the run counter as
+ [thread, #4]. Assert those too, since they are on the context-switch
+ critical path. */
+
+typedef char
+tx_port_assert_stack_ptr_offset_is_8[
+ (offsetof(TX_THREAD, tx_thread_stack_ptr) == 8) ? 1 : -1];
+
+typedef char
+tx_port_assert_run_count_offset_is_4[
+ (offsetof(TX_THREAD, tx_thread_run_count) == 4) ? 1 : -1];
diff --git a/ports/cortex_r52/gnu/src/tx_thread_context_restore.S b/ports/cortex_r52/gnu/src/tx_thread_context_restore.S
new file mode 100644
index 00000000..5c0e503d
--- /dev/null
+++ b/ports/cortex_r52/gnu/src/tx_thread_context_restore.S
@@ -0,0 +1,247 @@
+@/***************************************************************************
+@ * Copyright (c) 2024 Microsoft Corporation
+@ * Copyright (c) 2026 Eclipse ThreadX contributors
+@ *
+@ * This program and the accompanying materials are made available under the
+@ * terms of the MIT License which is available at
+@ * https://opensource.org/licenses/MIT.
+@ *
+@ * SPDX-License-Identifier: MIT
+@ **************************************************************************/
+@ Portions of this file were generated with AI assistance.
+@
+@
+@/**************************************************************************/
+@/**************************************************************************/
+@/** */
+@/** ThreadX Component */
+@/** */
+@/** Thread */
+@/** */
+@/**************************************************************************/
+@/**************************************************************************/
+#ifdef TX_INCLUDE_USER_DEFINE_FILE
+#include "tx_user.h"
+#endif
+
+ .arm
+
+#ifdef TX_ENABLE_FIQ_SUPPORT
+SVC_MODE = 0xD3 @ Disable IRQ/FIQ, SVC mode
+IRQ_MODE = 0xD2 @ Disable IRQ/FIQ, IRQ mode
+#else
+SVC_MODE = 0x93 @ Disable IRQ, SVC mode
+IRQ_MODE = 0x92 @ Disable IRQ, IRQ mode
+#endif
+@
+ .global _tx_thread_system_state
+ .global _tx_thread_current_ptr
+ .global _tx_thread_execute_ptr
+ .global _tx_timer_time_slice
+ .global _tx_thread_schedule
+ .global _tx_thread_preempt_disable
+ .global _tx_execution_isr_exit
+@
+@
+@/* No 16-bit Thumb mode veneer code is needed for _tx_thread_context_restore
+@ since it will never be called 16-bit mode. */
+@
+ .arm
+ .text
+ .align 2
+@/**************************************************************************/
+@/* */
+@/* FUNCTION RELEASE */
+@/* */
+@/* _tx_thread_context_restore Cortex-R52/GNU */
+@/* 6.5.2 */
+@/* AUTHOR */
+@/* */
+@/* Frédéric Desbiens, Eclipse Foundation */
+@/* */
+@/* Derived from the Cortex-R5/GNU port originally written by */
+@/* William E. Lamie, Microsoft Corporation. */
+@/* */
+@/* DESCRIPTION */
+@/* */
+@/* This function restores the interrupt context if it is processing a */
+@/* nested interrupt. If not, it returns to the interrupt thread if no */
+@/* preemption is necessary. Otherwise, if preemption is necessary or */
+@/* if no thread was running, the function returns to the scheduler. */
+@/* */
+@/* INPUT */
+@/* */
+@/* None */
+@/* */
+@/* OUTPUT */
+@/* */
+@/* None */
+@/* */
+@/* CALLS */
+@/* */
+@/* _tx_thread_schedule Thread scheduling routine */
+@/* */
+@/* CALLED BY */
+@/* */
+@/* ISRs Interrupt Service Routines */
+@/* */
+@/**************************************************************************/
+@VOID _tx_thread_context_restore(VOID)
+@{
+ .global _tx_thread_context_restore
+ .type _tx_thread_context_restore,function
+_tx_thread_context_restore:
+@
+@ /* Lockout interrupts. */
+@
+#ifdef TX_ENABLE_FIQ_SUPPORT
+ CPSID if @ Disable IRQ and FIQ interrupts
+#else
+ CPSID i @ Disable IRQ interrupts
+#endif
+
+#ifdef TX_ENABLE_EXECUTION_CHANGE_NOTIFY
+@
+@ /* Call the ISR exit function to indicate an ISR is complete. */
+@
+ BL _tx_execution_isr_exit @ Call the ISR exit function
+#endif
+@
+@ /* Determine if interrupts are nested. */
+@ if (--_tx_thread_system_state)
+@ {
+@
+ LDR r3, =_tx_thread_system_state @ Pickup address of system state variable
+ LDR r2, [r3] @ Pickup system state
+ SUB r2, r2, #1 @ Decrement the counter
+ STR r2, [r3] @ Store the counter
+ CMP r2, #0 @ Was this the first interrupt?
+ BEQ __tx_thread_not_nested_restore @ If so, not a nested restore
+@
+@ /* Interrupts are nested. */
+@
+@ /* Just recover the saved registers and return to the point of
+@ interrupt. */
+@
+ LDMIA sp!, {r0, r10, r12, lr} @ Recover SPSR, POI, and scratch regs
+ MSR SPSR_cxsf, r0 @ Put SPSR back
+ LDMIA sp!, {r0-r3} @ Recover r0-r3
+ MOVS pc, lr @ Return to point of interrupt
+@
+@ }
+__tx_thread_not_nested_restore:
+@
+@ /* Determine if a thread was interrupted and no preemption is required. */
+@ else if (((_tx_thread_current_ptr) && (_tx_thread_current_ptr == _tx_thread_execute_ptr))
+@ || (_tx_thread_preempt_disable))
+@ {
+@
+ LDR r1, =_tx_thread_current_ptr @ Pickup address of current thread ptr
+ LDR r0, [r1] @ Pickup actual current thread pointer
+ CMP r0, #0 @ Is it NULL?
+ BEQ __tx_thread_idle_system_restore @ Yes, idle system was interrupted
+@
+ LDR r3, =_tx_thread_preempt_disable @ Pickup preempt disable address
+ LDR r2, [r3] @ Pickup actual preempt disable flag
+ CMP r2, #0 @ Is it set?
+ BNE __tx_thread_no_preempt_restore @ Yes, don't preempt this thread
+ LDR r3, =_tx_thread_execute_ptr @ Pickup address of execute thread ptr
+ LDR r2, [r3] @ Pickup actual execute thread pointer
+ CMP r0, r2 @ Is the same thread highest priority?
+ BNE __tx_thread_preempt_restore @ No, preemption needs to happen
+@
+@
+__tx_thread_no_preempt_restore:
+@
+@ /* Restore interrupted thread or ISR. */
+@
+@ /* Pickup the saved stack pointer. */
+@ tmp_ptr = _tx_thread_current_ptr -> tx_thread_stack_ptr;
+@
+@ /* Recover the saved context and return to the point of interrupt. */
+@
+ LDMIA sp!, {r0, r10, r12, lr} @ Recover SPSR, POI, and scratch regs
+ MSR SPSR_cxsf, r0 @ Put SPSR back
+ LDMIA sp!, {r0-r3} @ Recover r0-r3
+ MOVS pc, lr @ Return to point of interrupt
+@
+@ }
+@ else
+@ {
+__tx_thread_preempt_restore:
+@
+ LDMIA sp!, {r3, r10, r12, lr} @ Recover temporarily saved registers
+ MOV r1, lr @ Save lr (point of interrupt)
+ MOV r2, #SVC_MODE @ Build SVC mode CPSR
+ MSR CPSR_c, r2 @ Enter SVC mode
+ STR r1, [sp, #-4]! @ Save point of interrupt
+ STMDB sp!, {r4-r12, lr} @ Save upper half of registers
+ MOV r4, r3 @ Save SPSR in r4
+ MOV r2, #IRQ_MODE @ Build IRQ mode CPSR
+ MSR CPSR_c, r2 @ Enter IRQ mode
+ LDMIA sp!, {r0-r3} @ Recover r0-r3
+ MOV r5, #SVC_MODE @ Build SVC mode CPSR
+ MSR CPSR_c, r5 @ Enter SVC mode
+ STMDB sp!, {r0-r3} @ Save r0-r3 on thread's stack
+@
+ LDR r1, =_tx_thread_current_ptr @ Pickup address of current thread ptr
+ LDR r0, [r1] @ Pickup current thread pointer
+@
+#ifdef TX_ENABLE_VFP_SUPPORT
+ LDR r2, [r0, #144] @ Pickup the VFP enabled flag
+ CMP r2, #0 @ Is the VFP enabled?
+ BEQ _tx_skip_irq_vfp_save @ No, skip VFP IRQ save
+ VMRS r2, FPSCR @ Pickup the FPSCR
+ STR r2, [sp, #-4]! @ Save FPSCR
+ VSTMDB sp!, {D0-D15} @ Save D0-D15
+_tx_skip_irq_vfp_save:
+#endif
+@
+ MOV r3, #1 @ Build interrupt stack type
+ STMDB sp!, {r3, r4} @ Save interrupt stack type and SPSR
+ STR sp, [r0, #8] @ Save stack pointer in thread control
+ @ block
+@
+@ /* Save the remaining time-slice and disable it. */
+@ if (_tx_timer_time_slice)
+@ {
+@
+ LDR r3, =_tx_timer_time_slice @ Pickup time-slice variable address
+ LDR r2, [r3] @ Pickup time-slice
+ CMP r2, #0 @ Is it active?
+ BEQ __tx_thread_dont_save_ts @ No, don't save it
+@
+@ _tx_thread_current_ptr -> tx_thread_time_slice = _tx_timer_time_slice;
+@ _tx_timer_time_slice = 0;
+@
+ STR r2, [r0, #24] @ Save thread's time-slice
+ MOV r2, #0 @ Clear value
+ STR r2, [r3] @ Disable global time-slice flag
+@
+@ }
+__tx_thread_dont_save_ts:
+@
+@
+@ /* Clear the current task pointer. */
+@ _tx_thread_current_ptr = TX_NULL;
+@
+ MOV r0, #0 @ NULL value
+ STR r0, [r1] @ Clear current thread pointer
+@
+@ /* Return to the scheduler. */
+@ _tx_thread_schedule();
+@
+ B _tx_thread_schedule @ Return to scheduler
+@ }
+@
+__tx_thread_idle_system_restore:
+@
+@ /* Just return back to the scheduler! */
+@
+ MOV r0, #SVC_MODE @ Build SVC mode CPSR
+ MSR CPSR_c, r0 @ Enter SVC mode
+ B _tx_thread_schedule @ Return to scheduler
+@}
+
+
+
diff --git a/ports/cortex_r52/gnu/src/tx_thread_context_save.S b/ports/cortex_r52/gnu/src/tx_thread_context_save.S
new file mode 100644
index 00000000..26443700
--- /dev/null
+++ b/ports/cortex_r52/gnu/src/tx_thread_context_save.S
@@ -0,0 +1,193 @@
+@/***************************************************************************
+@ * Copyright (c) 2024 Microsoft Corporation
+@ * Copyright (c) 2026 Eclipse ThreadX contributors
+@ *
+@ * This program and the accompanying materials are made available under the
+@ * terms of the MIT License which is available at
+@ * https://opensource.org/licenses/MIT.
+@ *
+@ * SPDX-License-Identifier: MIT
+@ **************************************************************************/
+@ Portions of this file were generated with AI assistance.
+@
+@
+@/**************************************************************************/
+@/**************************************************************************/
+@/** */
+@/** ThreadX Component */
+@/** */
+@/** Thread */
+@/** */
+@/**************************************************************************/
+@/**************************************************************************/
+#ifdef TX_INCLUDE_USER_DEFINE_FILE
+#include "tx_user.h"
+#endif
+
+ .global _tx_thread_system_state
+ .global _tx_thread_current_ptr
+ .global _tx_irq_processing_return
+ .global _tx_execution_isr_enter
+@
+@
+@/* No 16-bit Thumb mode veneer code is needed for _tx_thread_context_save
+@ since it will never be called 16-bit mode. */
+@
+ .arm
+ .text
+ .align 2
+@/**************************************************************************/
+@/* */
+@/* FUNCTION RELEASE */
+@/* */
+@/* _tx_thread_context_save Cortex-R52/GNU */
+@/* 6.5.2 */
+@/* AUTHOR */
+@/* */
+@/* Frédéric Desbiens, Eclipse Foundation */
+@/* */
+@/* Derived from the Cortex-R5/GNU port originally written by */
+@/* William E. Lamie, Microsoft Corporation. */
+@/* */
+@/* DESCRIPTION */
+@/* */
+@/* This function saves the context of an executing thread in the */
+@/* beginning of interrupt processing. The function also ensures that */
+@/* the system stack is used upon return to the calling ISR. */
+@/* */
+@/* INPUT */
+@/* */
+@/* None */
+@/* */
+@/* OUTPUT */
+@/* */
+@/* None */
+@/* */
+@/* CALLS */
+@/* */
+@/* None */
+@/* */
+@/* CALLED BY */
+@/* */
+@/* ISRs */
+@/* */
+@/**************************************************************************/
+@VOID _tx_thread_context_save(VOID)
+@{
+ .global _tx_thread_context_save
+ .type _tx_thread_context_save,function
+_tx_thread_context_save:
+@
+@ /* Upon entry to this routine, it is assumed that IRQ interrupts are locked
+@ out, we are in IRQ mode, and all registers are intact. */
+@
+@ /* Check for a nested interrupt condition. */
+@ if (_tx_thread_system_state++)
+@ {
+@
+ STMDB sp!, {r0-r3} @ Save some working registers
+#ifdef TX_ENABLE_FIQ_SUPPORT
+ CPSID if @ Disable FIQ interrupts
+#endif
+ LDR r3, =_tx_thread_system_state @ Pickup address of system state variable
+ LDR r2, [r3] @ Pickup system state
+ CMP r2, #0 @ Is this the first interrupt?
+ BEQ __tx_thread_not_nested_save @ Yes, not a nested context save
+@
+@ /* Nested interrupt condition. */
+@
+ ADD r2, r2, #1 @ Increment the interrupt counter
+ STR r2, [r3] @ Store it back in the variable
+@
+@ /* Save the rest of the scratch registers on the stack and return to the
+@ calling ISR. */
+@
+ MRS r0, SPSR @ Pickup saved SPSR
+ SUB lr, lr, #4 @ Adjust point of interrupt
+ STMDB sp!, {r0, r10, r12, lr} @ Store other registers
+@
+@ /* Return to the ISR. */
+@
+ MOV r10, #0 @ Clear stack limit
+
+#ifdef TX_ENABLE_EXECUTION_CHANGE_NOTIFY
+@
+@ /* Call the ISR enter function to indicate an ISR is executing. */
+@
+ PUSH {lr} @ Save ISR lr
+ BL _tx_execution_isr_enter @ Call the ISR enter function
+ POP {lr} @ Recover ISR lr
+#endif
+
+ B __tx_irq_processing_return @ Continue IRQ processing
+@
+__tx_thread_not_nested_save:
+@ }
+@
+@ /* Otherwise, not nested, check to see if a thread was running. */
+@ else if (_tx_thread_current_ptr)
+@ {
+@
+ ADD r2, r2, #1 @ Increment the interrupt counter
+ STR r2, [r3] @ Store it back in the variable
+ LDR r1, =_tx_thread_current_ptr @ Pickup address of current thread ptr
+ LDR r0, [r1] @ Pickup current thread pointer
+ CMP r0, #0 @ Is it NULL?
+ BEQ __tx_thread_idle_system_save @ If so, interrupt occurred in
+ @ scheduling loop - nothing needs saving!
+@
+@ /* Save minimal context of interrupted thread. */
+@
+ MRS r2, SPSR @ Pickup saved SPSR
+ SUB lr, lr, #4 @ Adjust point of interrupt
+ STMDB sp!, {r2, r10, r12, lr} @ Store other registers
+@
+@ /* Save the current stack pointer in the thread's control block. */
+@ _tx_thread_current_ptr -> tx_thread_stack_ptr = sp;
+@
+@ /* Switch to the system stack. */
+@ sp = _tx_thread_system_stack_ptr@
+@
+ MOV r10, #0 @ Clear stack limit
+
+#ifdef TX_ENABLE_EXECUTION_CHANGE_NOTIFY
+@
+@ /* Call the ISR enter function to indicate an ISR is executing. */
+@
+ PUSH {lr} @ Save ISR lr
+ BL _tx_execution_isr_enter @ Call the ISR enter function
+ POP {lr} @ Recover ISR lr
+#endif
+
+ B __tx_irq_processing_return @ Continue IRQ processing
+@
+@ }
+@ else
+@ {
+@
+__tx_thread_idle_system_save:
+@
+@ /* Interrupt occurred in the scheduling loop. */
+@
+@ /* Not much to do here, just adjust the stack pointer, and return to IRQ
+@ processing. */
+@
+ MOV r10, #0 @ Clear stack limit
+
+#ifdef TX_ENABLE_EXECUTION_CHANGE_NOTIFY
+@
+@ /* Call the ISR enter function to indicate an ISR is executing. */
+@
+ PUSH {lr} @ Save ISR lr
+ BL _tx_execution_isr_enter @ Call the ISR enter function
+ POP {lr} @ Recover ISR lr
+#endif
+
+ ADD sp, sp, #16 @ Recover saved registers
+ B __tx_irq_processing_return @ Continue IRQ processing
+@
+@ }
+@}
+
+
+
diff --git a/ports/cortex_r52/gnu/src/tx_thread_fiq_context_restore.S b/ports/cortex_r52/gnu/src/tx_thread_fiq_context_restore.S
new file mode 100644
index 00000000..f47c9662
--- /dev/null
+++ b/ports/cortex_r52/gnu/src/tx_thread_fiq_context_restore.S
@@ -0,0 +1,237 @@
+@/***************************************************************************
+@ * Copyright (c) 2024 Microsoft Corporation
+@ * Copyright (c) 2026 Eclipse ThreadX contributors
+@ *
+@ * This program and the accompanying materials are made available under the
+@ * terms of the MIT License which is available at
+@ * https://opensource.org/licenses/MIT.
+@ *
+@ * SPDX-License-Identifier: MIT
+@ **************************************************************************/
+@ Portions of this file were generated with AI assistance.
+@
+@
+@/**************************************************************************/
+@/**************************************************************************/
+@/** */
+@/** ThreadX Component */
+@/** */
+@/** Thread */
+@/** */
+@/**************************************************************************/
+@/**************************************************************************/
+#ifdef TX_INCLUDE_USER_DEFINE_FILE
+#include "tx_user.h"
+#endif
+
+SVC_MODE = 0xD3 @ SVC mode
+FIQ_MODE = 0xD1 @ FIQ mode
+MODE_MASK = 0x1F @ Mode mask
+THUMB_MASK = 0x20 @ Thumb bit mask
+IRQ_MODE_BITS = 0x12 @ IRQ mode bits
+@
+@
+ .global _tx_thread_system_state
+ .global _tx_thread_current_ptr
+ .global _tx_thread_system_stack_ptr
+ .global _tx_thread_execute_ptr
+ .global _tx_timer_time_slice
+ .global _tx_thread_schedule
+ .global _tx_thread_preempt_disable
+ .global _tx_execution_isr_exit
+@
+@
+@/* No 16-bit Thumb mode veneer code is needed for _tx_thread_fiq_context_restore
+@ since it will never be called 16-bit mode. */
+@
+ .arm
+ .text
+ .align 2
+@/**************************************************************************/
+@/* */
+@/* FUNCTION RELEASE */
+@/* */
+@/* _tx_thread_fiq_context_restore Cortex-R52/GNU */
+@/* 6.5.2 */
+@/* AUTHOR */
+@/* */
+@/* Frédéric Desbiens, Eclipse Foundation */
+@/* */
+@/* Derived from the Cortex-R5/GNU port originally written by */
+@/* William E. Lamie, Microsoft Corporation. */
+@/* */
+@/* DESCRIPTION */
+@/* */
+@/* This function restores the fiq interrupt context when processing a */
+@/* nested interrupt. If not, it returns to the interrupt thread if no */
+@/* preemption is necessary. Otherwise, if preemption is necessary or */
+@/* if no thread was running, the function returns to the scheduler. */
+@/* */
+@/* INPUT */
+@/* */
+@/* None */
+@/* */
+@/* OUTPUT */
+@/* */
+@/* None */
+@/* */
+@/* CALLS */
+@/* */
+@/* _tx_thread_schedule Thread scheduling routine */
+@/* */
+@/* CALLED BY */
+@/* */
+@/* FIQ ISR Interrupt Service Routines */
+@/* */
+@/**************************************************************************/
+@VOID _tx_thread_fiq_context_restore(VOID)
+@{
+ .global _tx_thread_fiq_context_restore
+ .type _tx_thread_fiq_context_restore,function
+_tx_thread_fiq_context_restore:
+@
+@ /* Lockout interrupts. */
+@
+ CPSID if @ Disable IRQ and FIQ interrupts
+
+#ifdef TX_ENABLE_EXECUTION_CHANGE_NOTIFY
+@
+@ /* Call the ISR exit function to indicate an ISR is complete. */
+@
+ BL _tx_execution_isr_exit @ Call the ISR exit function
+#endif
+@
+@ /* Determine if interrupts are nested. */
+@ if (--_tx_thread_system_state)
+@ {
+@
+ LDR r3, =_tx_thread_system_state @ Pickup address of system state variable
+ LDR r2, [r3] @ Pickup system state
+ SUB r2, r2, #1 @ Decrement the counter
+ STR r2, [r3] @ Store the counter
+ CMP r2, #0 @ Was this the first interrupt?
+ BEQ __tx_thread_fiq_not_nested_restore @ If so, not a nested restore
+@
+@ /* Interrupts are nested. */
+@
+@ /* Just recover the saved registers and return to the point of
+@ interrupt. */
+@
+ LDMIA sp!, {r0, r10, r12, lr} @ Recover SPSR, POI, and scratch regs
+ MSR SPSR_cxsf, r0 @ Put SPSR back
+ LDMIA sp!, {r0-r3} @ Recover r0-r3
+ MOVS pc, lr @ Return to point of interrupt
+@
+@ }
+__tx_thread_fiq_not_nested_restore:
+@
+@ /* Determine if a thread was interrupted and no preemption is required. */
+@ else if (((_tx_thread_current_ptr) && (_tx_thread_current_ptr == _tx_thread_execute_ptr))
+@ || (_tx_thread_preempt_disable))
+@ {
+@
+ LDR r1, [sp] @ Pickup the saved SPSR
+ MOV r2, #MODE_MASK @ Build mask to isolate the interrupted mode
+ AND r1, r1, r2 @ Isolate mode bits
+ CMP r1, #IRQ_MODE_BITS @ Was an interrupt taken in IRQ mode before we
+ @ got to context save? */
+ BEQ __tx_thread_fiq_no_preempt_restore @ Yes, just go back to point of interrupt
+
+
+ LDR r1, =_tx_thread_current_ptr @ Pickup address of current thread ptr
+ LDR r0, [r1] @ Pickup actual current thread pointer
+ CMP r0, #0 @ Is it NULL?
+ BEQ __tx_thread_fiq_idle_system_restore @ Yes, idle system was interrupted
+
+ LDR r3, =_tx_thread_preempt_disable @ Pickup preempt disable address
+ LDR r2, [r3] @ Pickup actual preempt disable flag
+ CMP r2, #0 @ Is it set?
+ BNE __tx_thread_fiq_no_preempt_restore @ Yes, don't preempt this thread
+ LDR r3, =_tx_thread_execute_ptr @ Pickup address of execute thread ptr
+ LDR r2, [r3] @ Pickup actual execute thread pointer
+ CMP r0, r2 @ Is the same thread highest priority?
+ BNE __tx_thread_fiq_preempt_restore @ No, preemption needs to happen
+
+
+__tx_thread_fiq_no_preempt_restore:
+@
+@ /* Restore interrupted thread or ISR. */
+@
+@ /* Pickup the saved stack pointer. */
+@ tmp_ptr = _tx_thread_current_ptr -> tx_thread_stack_ptr;
+@
+@ /* Recover the saved context and return to the point of interrupt. */
+@
+ LDMIA sp!, {r0, lr} @ Recover SPSR, POI, and scratch regs
+ MSR SPSR_cxsf, r0 @ Put SPSR back
+ LDMIA sp!, {r0-r3} @ Recover r0-r3
+ MOVS pc, lr @ Return to point of interrupt
+@
+@ }
+@ else
+@ {
+__tx_thread_fiq_preempt_restore:
+@
+ LDMIA sp!, {r3, lr} @ Recover temporarily saved registers
+ MOV r1, lr @ Save lr (point of interrupt)
+ MOV r2, #SVC_MODE @ Build SVC mode CPSR
+ MSR CPSR_c, r2 @ Enter SVC mode
+ STR r1, [sp, #-4]! @ Save point of interrupt
+ STMDB sp!, {r4-r12, lr} @ Save upper half of registers
+ MOV r4, r3 @ Save SPSR in r4
+ MOV r2, #FIQ_MODE @ Build FIQ mode CPSR
+ MSR CPSR_c, r2 @ Reenter FIQ mode
+ LDMIA sp!, {r0-r3} @ Recover r0-r3
+ MOV r5, #SVC_MODE @ Build SVC mode CPSR
+ MSR CPSR_c, r5 @ Enter SVC mode
+ STMDB sp!, {r0-r3} @ Save r0-r3 on thread's stack
+ MOV r3, #1 @ Build interrupt stack type
+ STMDB sp!, {r3, r4} @ Save interrupt stack type and SPSR
+ LDR r1, =_tx_thread_current_ptr @ Pickup address of current thread ptr
+ LDR r0, [r1] @ Pickup current thread pointer
+ STR sp, [r0, #8] @ Save stack pointer in thread control
+ @ block */
+@
+@ /* Save the remaining time-slice and disable it. */
+@ if (_tx_timer_time_slice)
+@ {
+@
+ LDR r3, =_tx_timer_time_slice @ Pickup time-slice variable address
+ LDR r2, [r3] @ Pickup time-slice
+ CMP r2, #0 @ Is it active?
+ BEQ __tx_thread_fiq_dont_save_ts @ No, don't save it
+@
+@ _tx_thread_current_ptr -> tx_thread_time_slice = _tx_timer_time_slice;
+@ _tx_timer_time_slice = 0;
+@
+ STR r2, [r0, #24] @ Save thread's time-slice
+ MOV r2, #0 @ Clear value
+ STR r2, [r3] @ Disable global time-slice flag
+@
+@ }
+__tx_thread_fiq_dont_save_ts:
+@
+@
+@ /* Clear the current task pointer. */
+@ _tx_thread_current_ptr = TX_NULL;
+@
+ MOV r0, #0 @ NULL value
+ STR r0, [r1] @ Clear current thread pointer
+@
+@ /* Return to the scheduler. */
+@ _tx_thread_schedule();
+@
+ B _tx_thread_schedule @ Return to scheduler
+@ }
+@
+__tx_thread_fiq_idle_system_restore:
+@
+@ /* Just return back to the scheduler! */
+@
+ ADD sp, sp, #24 @ Recover FIQ stack space
+ MOV r3, #SVC_MODE @ Build SVC mode CPSR
+ MSR CPSR_c, r3 @ Lockout interrupts
+ B _tx_thread_schedule @ Return to scheduler
+@
+@}
+
diff --git a/ports/cortex_r52/gnu/src/tx_thread_fiq_context_save.S b/ports/cortex_r52/gnu/src/tx_thread_fiq_context_save.S
new file mode 100644
index 00000000..510fe36e
--- /dev/null
+++ b/ports/cortex_r52/gnu/src/tx_thread_fiq_context_save.S
@@ -0,0 +1,195 @@
+@/***************************************************************************
+@ * Copyright (c) 2024 Microsoft Corporation
+@ * Copyright (c) 2026 Eclipse ThreadX contributors
+@ *
+@ * This program and the accompanying materials are made available under the
+@ * terms of the MIT License which is available at
+@ * https://opensource.org/licenses/MIT.
+@ *
+@ * SPDX-License-Identifier: MIT
+@ **************************************************************************/
+@ Portions of this file were generated with AI assistance.
+@
+@
+@/**************************************************************************/
+@/**************************************************************************/
+@/** */
+@/** ThreadX Component */
+@/** */
+@/** Thread */
+@/** */
+@/**************************************************************************/
+@/**************************************************************************/
+#ifdef TX_INCLUDE_USER_DEFINE_FILE
+#include "tx_user.h"
+#endif
+
+ .global _tx_thread_system_state
+ .global _tx_thread_current_ptr
+ .global __tx_fiq_processing_return
+ .global _tx_execution_isr_enter
+@
+@
+@/* No 16-bit Thumb mode veneer code is needed for _tx_thread_fiq_context_save
+@ since it will never be called 16-bit mode. */
+@
+ .arm
+ .text
+ .align 2
+@/**************************************************************************/
+@/* */
+@/* FUNCTION RELEASE */
+@/* */
+@/* _tx_thread_fiq_context_save Cortex-R52/GNU */
+@/* 6.5.2 */
+@/* AUTHOR */
+@/* */
+@/* Frédéric Desbiens, Eclipse Foundation */
+@/* */
+@/* Derived from the Cortex-R5/GNU port originally written by */
+@/* William E. Lamie, Microsoft Corporation. */
+@/* */
+@/* DESCRIPTION */
+@/* */
+@/* This function saves the context of an executing thread in the */
+@/* beginning of interrupt processing. The function also ensures that */
+@/* the system stack is used upon return to the calling ISR. */
+@/* */
+@/* INPUT */
+@/* */
+@/* None */
+@/* */
+@/* OUTPUT */
+@/* */
+@/* None */
+@/* */
+@/* CALLS */
+@/* */
+@/* None */
+@/* */
+@/* CALLED BY */
+@/* */
+@/* ISRs */
+@/* */
+@/**************************************************************************/
+@ VOID _tx_thread_fiq_context_save(VOID)
+@{
+ .global _tx_thread_fiq_context_save
+ .type _tx_thread_fiq_context_save,function
+_tx_thread_fiq_context_save:
+@
+@ /* Upon entry to this routine, it is assumed that IRQ interrupts are locked
+@ out, we are in IRQ mode, and all registers are intact. */
+@
+@ /* Check for a nested interrupt condition. */
+@ if (_tx_thread_system_state++)
+@ {
+@
+ STMDB sp!, {r0-r3} @ Save some working registers
+ LDR r3, =_tx_thread_system_state @ Pickup address of system state variable
+ LDR r2, [r3] @ Pickup system state
+ CMP r2, #0 @ Is this the first interrupt?
+ BEQ __tx_thread_fiq_not_nested_save @ Yes, not a nested context save
+@
+@ /* Nested interrupt condition. */
+@
+ ADD r2, r2, #1 @ Increment the interrupt counter
+ STR r2, [r3] @ Store it back in the variable
+@
+@ /* Save the rest of the scratch registers on the stack and return to the
+@ calling ISR. */
+@
+ MRS r0, SPSR @ Pickup saved SPSR
+ SUB lr, lr, #4 @ Adjust point of interrupt
+ STMDB sp!, {r0, r10, r12, lr} @ Store other registers
+@
+@ /* Return to the ISR. */
+@
+ MOV r10, #0 @ Clear stack limit
+
+#ifdef TX_ENABLE_EXECUTION_CHANGE_NOTIFY
+@
+@ /* Call the ISR enter function to indicate an ISR is executing. */
+@
+ PUSH {lr} @ Save ISR lr
+ BL _tx_execution_isr_enter @ Call the ISR enter function
+ POP {lr} @ Recover ISR lr
+#endif
+
+ B __tx_fiq_processing_return @ Continue FIQ processing
+@
+__tx_thread_fiq_not_nested_save:
+@ }
+@
+@ /* Otherwise, not nested, check to see if a thread was running. */
+@ else if (_tx_thread_current_ptr)
+@ {
+@
+ ADD r2, r2, #1 @ Increment the interrupt counter
+ STR r2, [r3] @ Store it back in the variable
+ LDR r1, =_tx_thread_current_ptr @ Pickup address of current thread ptr
+ LDR r0, [r1] @ Pickup current thread pointer
+ CMP r0, #0 @ Is it NULL?
+ BEQ __tx_thread_fiq_idle_system_save @ If so, interrupt occurred in
+@ @ scheduling loop - nothing needs saving!
+@
+@ /* Save minimal context of interrupted thread. */
+@
+ MRS r2, SPSR @ Pickup saved SPSR
+ SUB lr, lr, #4 @ Adjust point of interrupt
+ STMDB sp!, {r2, lr} @ Store other registers, Note that we don't
+@ @ need to save sl and ip since FIQ has
+@ @ copies of these registers. Nested
+@ @ interrupt processing does need to save
+@ @ these registers.
+@
+@ /* Save the current stack pointer in the thread's control block. */
+@ _tx_thread_current_ptr -> tx_thread_stack_ptr = sp;
+@
+@ /* Switch to the system stack. */
+@ sp = _tx_thread_system_stack_ptr;
+@
+ MOV r10, #0 @ Clear stack limit
+
+#ifdef TX_ENABLE_EXECUTION_CHANGE_NOTIFY
+@
+@ /* Call the ISR enter function to indicate an ISR is executing. */
+@
+ PUSH {lr} @ Save ISR lr
+ BL _tx_execution_isr_enter @ Call the ISR enter function
+ POP {lr} @ Recover ISR lr
+#endif
+
+ B __tx_fiq_processing_return @ Continue FIQ processing
+@
+@ }
+@ else
+@ {
+@
+__tx_thread_fiq_idle_system_save:
+@
+@ /* Interrupt occurred in the scheduling loop. */
+@
+#ifdef TX_ENABLE_EXECUTION_CHANGE_NOTIFY
+@
+@ /* Call the ISR enter function to indicate an ISR is executing. */
+@
+ PUSH {lr} @ Save ISR lr
+ BL _tx_execution_isr_enter @ Call the ISR enter function
+ POP {lr} @ Recover ISR lr
+#endif
+@
+@ /* Not much to do here, save the current SPSR and LR for possible
+@ use in IRQ interrupted in idle system conditions, and return to
+@ FIQ interrupt processing. */
+@
+ MRS r0, SPSR @ Pickup saved SPSR
+ SUB lr, lr, #4 @ Adjust point of interrupt
+ STMDB sp!, {r0, lr} @ Store other registers that will get used
+@ @ or stripped off the stack in context
+@ @ restore
+ B __tx_fiq_processing_return @ Continue FIQ processing
+@
+@ }
+@}
+
diff --git a/ports/cortex_r52/gnu/src/tx_thread_fiq_nesting_end.S b/ports/cortex_r52/gnu/src/tx_thread_fiq_nesting_end.S
new file mode 100644
index 00000000..5b323208
--- /dev/null
+++ b/ports/cortex_r52/gnu/src/tx_thread_fiq_nesting_end.S
@@ -0,0 +1,107 @@
+@/***************************************************************************
+@ * Copyright (c) 2024 Microsoft Corporation
+@ * Copyright (c) 2026 Eclipse ThreadX contributors
+@ *
+@ * This program and the accompanying materials are made available under the
+@ * terms of the MIT License which is available at
+@ * https://opensource.org/licenses/MIT.
+@ *
+@ * SPDX-License-Identifier: MIT
+@ **************************************************************************/
+@ Portions of this file were generated with AI assistance.
+@
+@
+@/**************************************************************************/
+@/**************************************************************************/
+@/** */
+@/** ThreadX Component */
+@/** */
+@/** Thread */
+@/** */
+@/**************************************************************************/
+@/**************************************************************************/
+#ifdef TX_INCLUDE_USER_DEFINE_FILE
+#include "tx_user.h"
+#endif
+
+#ifdef TX_ENABLE_FIQ_SUPPORT
+DISABLE_INTS = 0xC0 @ Disable IRQ/FIQ interrupts
+#else
+DISABLE_INTS = 0x80 @ Disable IRQ interrupts
+#endif
+MODE_MASK = 0x1F @ Mode mask
+FIQ_MODE_BITS = 0x11 @ FIQ mode bits
+@
+@
+@/* No 16-bit Thumb mode veneer code is needed for _tx_thread_fiq_nesting_end
+@ since it will never be called 16-bit mode. */
+@
+ .arm
+ .text
+ .align 2
+@/**************************************************************************/
+@/* */
+@/* FUNCTION RELEASE */
+@/* */
+@/* _tx_thread_fiq_nesting_end Cortex-R52/GNU */
+@/* 6.5.2 */
+@/* AUTHOR */
+@/* */
+@/* Frédéric Desbiens, Eclipse Foundation */
+@/* */
+@/* Derived from the Cortex-R5/GNU port originally written by */
+@/* William E. Lamie, Microsoft Corporation. */
+@/* */
+@/* DESCRIPTION */
+@/* */
+@/* This function is called by the application from FIQ mode after */
+@/* _tx_thread_fiq_nesting_start has been called and switches the FIQ */
+@/* processing from system mode back to FIQ mode prior to the ISR */
+@/* calling _tx_thread_fiq_context_restore. Note that this function */
+@/* assumes the system stack pointer is in the same position after */
+@/* nesting start function was called. */
+@/* */
+@/* This function assumes that the system mode stack pointer was setup */
+@/* during low-level initialization (tx_initialize_low_level.s). */
+@/* */
+@/* This function returns with FIQ interrupts disabled. */
+@/* */
+@/* INPUT */
+@/* */
+@/* None */
+@/* */
+@/* OUTPUT */
+@/* */
+@/* None */
+@/* */
+@/* CALLS */
+@/* */
+@/* None */
+@/* */
+@/* CALLED BY */
+@/* */
+@/* ISRs */
+@/* */
+@/**************************************************************************/
+@VOID _tx_thread_fiq_nesting_end(VOID)
+@{
+ .global _tx_thread_fiq_nesting_end
+ .type _tx_thread_fiq_nesting_end,function
+_tx_thread_fiq_nesting_end:
+ MOV r3,lr @ Save ISR return address
+ MRS r0, CPSR @ Pickup the CPSR
+ ORR r0, r0, #DISABLE_INTS @ Build disable interrupt value
+ MSR CPSR_c, r0 @ Disable interrupts
+ LDMIA sp!, {r1, lr} @ Pickup saved lr (and r1 throw-away for
+ @ 8-byte alignment logic)
+ BIC r0, r0, #MODE_MASK @ Clear mode bits
+ ORR r0, r0, #FIQ_MODE_BITS @ Build IRQ mode CPSR
+ MSR CPSR_c, r0 @ Reenter IRQ mode
+
+#ifdef __THUMB_INTERWORK
+ BX r3 @ Return to caller
+#else
+ MOV pc, r3 @ Return to caller
+#endif
+@}
+
diff --git a/ports/cortex_r52/gnu/src/tx_thread_fiq_nesting_start.S b/ports/cortex_r52/gnu/src/tx_thread_fiq_nesting_start.S
new file mode 100644
index 00000000..516eef63
--- /dev/null
+++ b/ports/cortex_r52/gnu/src/tx_thread_fiq_nesting_start.S
@@ -0,0 +1,99 @@
+@/***************************************************************************
+@ * Copyright (c) 2024 Microsoft Corporation
+@ * Copyright (c) 2026 Eclipse ThreadX contributors
+@ *
+@ * This program and the accompanying materials are made available under the
+@ * terms of the MIT License which is available at
+@ * https://opensource.org/licenses/MIT.
+@ *
+@ * SPDX-License-Identifier: MIT
+@ **************************************************************************/
+@ Portions of this file were generated with AI assistance.
+@
+@
+@/**************************************************************************/
+@/**************************************************************************/
+@/** */
+@/** ThreadX Component */
+@/** */
+@/** Thread */
+@/** */
+@/**************************************************************************/
+@/**************************************************************************/
+#ifdef TX_INCLUDE_USER_DEFINE_FILE
+#include "tx_user.h"
+#endif
+
+FIQ_DISABLE = 0x40 @ FIQ disable bit
+MODE_MASK = 0x1F @ Mode mask
+SYS_MODE_BITS = 0x1F @ System mode bits
+@
+@
+@/* No 16-bit Thumb mode veneer code is needed for _tx_thread_fiq_nesting_start
+@ since it will never be called 16-bit mode. */
+@
+ .arm
+ .text
+ .align 2
+@/**************************************************************************/
+@/* */
+@/* FUNCTION RELEASE */
+@/* */
+@/* _tx_thread_fiq_nesting_start Cortex-R52/GNU */
+@/* 6.5.2 */
+@/* AUTHOR */
+@/* */
+@/* Frédéric Desbiens, Eclipse Foundation */
+@/* */
+@/* Derived from the Cortex-R5/GNU port originally written by */
+@/* William E. Lamie, Microsoft Corporation. */
+@/* */
+@/* DESCRIPTION */
+@/* */
+@/* This function is called by the application from FIQ mode after */
+@/* _tx_thread_fiq_context_save has been called and switches the FIQ */
+@/* processing to the system mode so nested FIQ interrupt processing */
+@/* is possible (system mode has its own "lr" register). Note that */
+@/* this function assumes that the system mode stack pointer was setup */
+@/* during low-level initialization (tx_initialize_low_level.s). */
+@/* */
+@/* This function returns with FIQ interrupts enabled. */
+@/* */
+@/* INPUT */
+@/* */
+@/* None */
+@/* */
+@/* OUTPUT */
+@/* */
+@/* None */
+@/* */
+@/* CALLS */
+@/* */
+@/* None */
+@/* */
+@/* CALLED BY */
+@/* */
+@/* ISRs */
+@/* */
+@/**************************************************************************/
+@VOID _tx_thread_fiq_nesting_start(VOID)
+@{
+ .global _tx_thread_fiq_nesting_start
+ .type _tx_thread_fiq_nesting_start,function
+_tx_thread_fiq_nesting_start:
+ MOV r3,lr @ Save ISR return address
+ MRS r0, CPSR @ Pickup the CPSR
+ BIC r0, r0, #MODE_MASK @ Clear the mode bits
+ ORR r0, r0, #SYS_MODE_BITS @ Build system mode CPSR
+ MSR CPSR_c, r0 @ Enter system mode
+ STMDB sp!, {r1, lr} @ Push the system mode lr on the system mode stack
+ @ and push r1 just to keep 8-byte alignment
+ BIC r0, r0, #FIQ_DISABLE @ Build enable FIQ CPSR
+ MSR CPSR_c, r0 @ Enter system mode
+#ifdef __THUMB_INTERWORK
+ BX r3 @ Return to caller
+#else
+ MOV pc, r3 @ Return to caller
+#endif
+@}
+
diff --git a/ports/cortex_r52/gnu/src/tx_thread_interrupt_control.S b/ports/cortex_r52/gnu/src/tx_thread_interrupt_control.S
new file mode 100644
index 00000000..3bc0e54a
--- /dev/null
+++ b/ports/cortex_r52/gnu/src/tx_thread_interrupt_control.S
@@ -0,0 +1,108 @@
+@/***************************************************************************
+@ * Copyright (c) 2024 Microsoft Corporation
+@ * Copyright (c) 2026 Eclipse ThreadX contributors
+@ *
+@ * This program and the accompanying materials are made available under the
+@ * terms of the MIT License which is available at
+@ * https://opensource.org/licenses/MIT.
+@ *
+@ * SPDX-License-Identifier: MIT
+@ **************************************************************************/
+@ Portions of this file were generated with AI assistance.
+@
+@
+@/**************************************************************************/
+@/**************************************************************************/
+@/** */
+@/** ThreadX Component */
+@/** */
+@/** Thread */
+@/** */
+@/**************************************************************************/
+@/**************************************************************************/
+#ifdef TX_INCLUDE_USER_DEFINE_FILE
+#include "tx_user.h"
+#endif
+
+
+INT_MASK = 0x03F
+
+@
+@/* Define the 16-bit Thumb mode veneer for _tx_thread_interrupt_control for
+@ applications calling this function from to 16-bit Thumb mode. */
+@
+ .text
+ .align 2
+ .global $_tx_thread_interrupt_control
+$_tx_thread_interrupt_control:
+ .thumb
+ BX pc @ Switch to 32-bit mode
+ NOP @
+ .arm
+ STMFD sp!, {lr} @ Save return address
+ BL _tx_thread_interrupt_control @ Call _tx_thread_interrupt_control function
+ LDMFD sp!, {lr} @ Recover saved return address
+ BX lr @ Return to 16-bit caller
+@
+@
+ .text
+ .align 2
+@/**************************************************************************/
+@/* */
+@/* FUNCTION RELEASE */
+@/* */
+@/* _tx_thread_interrupt_control Cortex-R52/GNU */
+@/* 6.5.2 */
+@/* AUTHOR */
+@/* */
+@/* Frédéric Desbiens, Eclipse Foundation */
+@/* */
+@/* Derived from the Cortex-R5/GNU port originally written by */
+@/* William E. Lamie, Microsoft Corporation. */
+@/* */
+@/* DESCRIPTION */
+@/* */
+@/* This function is responsible for changing the interrupt lockout */
+@/* posture of the system. */
+@/* */
+@/* INPUT */
+@/* */
+@/* new_posture New interrupt lockout posture */
+@/* */
+@/* OUTPUT */
+@/* */
+@/* old_posture Old interrupt lockout posture */
+@/* */
+@/* CALLS */
+@/* */
+@/* None */
+@/* */
+@/* CALLED BY */
+@/* */
+@/* Application Code */
+@/* */
+@/**************************************************************************/
+@UINT _tx_thread_interrupt_control(UINT new_posture)
+@{
+ .global _tx_thread_interrupt_control
+ .type _tx_thread_interrupt_control,function
+_tx_thread_interrupt_control:
+@
+@ /* Pickup current interrupt lockout posture. */
+@
+ MRS r3, CPSR @ Pickup current CPSR
+ MOV r2, #INT_MASK @ Build interrupt mask
+ AND r1, r3, r2 @ Clear interrupt lockout bits
+ ORR r1, r1, r0 @ Or-in new interrupt lockout bits
+@
+@ /* Apply the new interrupt posture. */
+@
+ MSR CPSR_c, r1 @ Setup new CPSR
+ BIC r0, r3, r2 @ Return previous interrupt mask
+#ifdef __THUMB_INTERWORK
+ BX lr @ Return to caller
+#else
+ MOV pc, lr @ Return to caller
+#endif
+@}
+
diff --git a/ports/cortex_r52/gnu/src/tx_thread_interrupt_disable.S b/ports/cortex_r52/gnu/src/tx_thread_interrupt_disable.S
new file mode 100644
index 00000000..9b3f215a
--- /dev/null
+++ b/ports/cortex_r52/gnu/src/tx_thread_interrupt_disable.S
@@ -0,0 +1,105 @@
+@/***************************************************************************
+@ * Copyright (c) 2024 Microsoft Corporation
+@ * Copyright (c) 2026 Eclipse ThreadX contributors
+@ *
+@ * This program and the accompanying materials are made available under the
+@ * terms of the MIT License which is available at
+@ * https://opensource.org/licenses/MIT.
+@ *
+@ * SPDX-License-Identifier: MIT
+@ **************************************************************************/
+@ Portions of this file were generated with AI assistance.
+@
+@
+@/**************************************************************************/
+@/**************************************************************************/
+@/** */
+@/** ThreadX Component */
+@/** */
+@/** Thread */
+@/** */
+@/**************************************************************************/
+@/**************************************************************************/
+#ifdef TX_INCLUDE_USER_DEFINE_FILE
+#include "tx_user.h"
+#endif
+
+@/* Define the 16-bit Thumb mode veneer for _tx_thread_interrupt_disable for
+@ applications calling this function from to 16-bit Thumb mode. */
+@
+ .text
+ .align 2
+ .global $_tx_thread_interrupt_disable
+$_tx_thread_interrupt_disable:
+ .thumb
+ BX pc @ Switch to 32-bit mode
+ NOP @
+ .arm
+ STMFD sp!, {lr} @ Save return address
+ BL _tx_thread_interrupt_disable @ Call _tx_thread_interrupt_disable function
+ LDMFD sp!, {lr} @ Recover saved return address
+ BX lr @ Return to 16-bit caller
+@
+@
+ .text
+ .align 2
+@/**************************************************************************/
+@/* */
+@/* FUNCTION RELEASE */
+@/* */
+@/* _tx_thread_interrupt_disable Cortex-R52/GNU */
+@/* 6.5.2 */
+@/* AUTHOR */
+@/* */
+@/* Frédéric Desbiens, Eclipse Foundation */
+@/* */
+@/* Derived from the Cortex-R5/GNU port originally written by */
+@/* William E. Lamie, Microsoft Corporation. */
+@/* */
+@/* DESCRIPTION */
+@/* */
+@/* This function is responsible for disabling interrupts */
+@/* */
+@/* INPUT */
+@/* */
+@/* None */
+@/* */
+@/* OUTPUT */
+@/* */
+@/* old_posture Old interrupt lockout posture */
+@/* */
+@/* CALLS */
+@/* */
+@/* None */
+@/* */
+@/* CALLED BY */
+@/* */
+@/* Application Code */
+@/* */
+@/**************************************************************************/
+@UINT _tx_thread_interrupt_disable(void)
+@{
+ .global _tx_thread_interrupt_disable
+ .type _tx_thread_interrupt_disable,function
+_tx_thread_interrupt_disable:
+@
+@ /* Pickup current interrupt lockout posture. */
+@
+ MRS r0, CPSR @ Pickup current CPSR
+@
+@ /* Mask interrupts. */
+@
+#ifdef TX_ENABLE_FIQ_SUPPORT
+ CPSID if @ Disable IRQ and FIQ
+#else
+ CPSID i @ Disable IRQ
+#endif
+
+#ifdef __THUMB_INTERWORK
+ BX lr @ Return to caller
+#else
+ MOV pc, lr @ Return to caller
+#endif
+@}
+
+
diff --git a/ports/cortex_r52/gnu/src/tx_thread_interrupt_restore.S b/ports/cortex_r52/gnu/src/tx_thread_interrupt_restore.S
new file mode 100644
index 00000000..b014afd9
--- /dev/null
+++ b/ports/cortex_r52/gnu/src/tx_thread_interrupt_restore.S
@@ -0,0 +1,96 @@
+@/***************************************************************************
+@ * Copyright (c) 2024 Microsoft Corporation
+@ * Copyright (c) 2026 Eclipse ThreadX contributors
+@ *
+@ * This program and the accompanying materials are made available under the
+@ * terms of the MIT License which is available at
+@ * https://opensource.org/licenses/MIT.
+@ *
+@ * SPDX-License-Identifier: MIT
+@ **************************************************************************/
+@ Portions of this file were generated with AI assistance.
+@
+@
+@/**************************************************************************/
+@/**************************************************************************/
+@/** */
+@/** ThreadX Component */
+@/** */
+@/** Thread */
+@/** */
+@/**************************************************************************/
+@/**************************************************************************/
+#ifdef TX_INCLUDE_USER_DEFINE_FILE
+#include "tx_user.h"
+#endif
+
+@/* Define the 16-bit Thumb mode veneer for _tx_thread_interrupt_restore for
+@ applications calling this function from to 16-bit Thumb mode. */
+@
+ .text
+ .align 2
+ .global $_tx_thread_interrupt_restore
+$_tx_thread_interrupt_restore:
+ .thumb
+ BX pc @ Switch to 32-bit mode
+ NOP @
+ .arm
+ STMFD sp!, {lr} @ Save return address
+ BL _tx_thread_interrupt_restore @ Call _tx_thread_interrupt_restore function
+ LDMFD sp!, {lr} @ Recover saved return address
+ BX lr @ Return to 16-bit caller
+@
+@
+ .text
+ .align 2
+@/**************************************************************************/
+@/* */
+@/* FUNCTION RELEASE */
+@/* */
+@/* _tx_thread_interrupt_restore Cortex-R52/GNU */
+@/* 6.5.2 */
+@/* AUTHOR */
+@/* */
+@/* Frédéric Desbiens, Eclipse Foundation */
+@/* */
+@/* Derived from the Cortex-R5/GNU port originally written by */
+@/* William E. Lamie, Microsoft Corporation. */
+@/* */
+@/* DESCRIPTION */
+@/* */
+@/* This function is responsible for restoring interrupts to the state */
+@/* returned by a previous _tx_thread_interrupt_disable call. */
+@/* */
+@/* INPUT */
+@/* */
+@/* old_posture Old interrupt lockout posture */
+@/* */
+@/* OUTPUT */
+@/* */
+@/* None */
+@/* */
+@/* CALLS */
+@/* */
+@/* None */
+@/* */
+@/* CALLED BY */
+@/* */
+@/* Application Code */
+@/* */
+@/**************************************************************************/
+@UINT _tx_thread_interrupt_restore(UINT old_posture)
+@{
+ .global _tx_thread_interrupt_restore
+ .type _tx_thread_interrupt_restore,function
+_tx_thread_interrupt_restore:
+@
+@ /* Apply the new interrupt posture. */
+@
+ MSR CPSR_c, r0 @ Setup new CPSR
+#ifdef __THUMB_INTERWORK
+ BX lr @ Return to caller
+#else
+ MOV pc, lr @ Return to caller
+#endif
+@}
+
diff --git a/ports/cortex_r52/gnu/src/tx_thread_irq_nesting_end.S b/ports/cortex_r52/gnu/src/tx_thread_irq_nesting_end.S
new file mode 100644
index 00000000..f14ce5cf
--- /dev/null
+++ b/ports/cortex_r52/gnu/src/tx_thread_irq_nesting_end.S
@@ -0,0 +1,106 @@
+@/***************************************************************************
+@ * Copyright (c) 2024 Microsoft Corporation
+@ * Copyright (c) 2026 Eclipse ThreadX contributors
+@ *
+@ * This program and the accompanying materials are made available under the
+@ * terms of the MIT License which is available at
+@ * https://opensource.org/licenses/MIT.
+@ *
+@ * SPDX-License-Identifier: MIT
+@ **************************************************************************/
+@ Portions of this file were generated with AI assistance.
+@
+@
+@/**************************************************************************/
+@/**************************************************************************/
+@/** */
+@/** ThreadX Component */
+@/** */
+@/** Thread */
+@/** */
+@/**************************************************************************/
+@/**************************************************************************/
+#ifdef TX_INCLUDE_USER_DEFINE_FILE
+#include "tx_user.h"
+#endif
+
+#ifdef TX_ENABLE_FIQ_SUPPORT
+DISABLE_INTS = 0xC0 @ Disable IRQ/FIQ interrupts
+#else
+DISABLE_INTS = 0x80 @ Disable IRQ interrupts
+#endif
+MODE_MASK = 0x1F @ Mode mask
+IRQ_MODE_BITS = 0x12 @ IRQ mode bits
+@
+@
+@/* No 16-bit Thumb mode veneer code is needed for _tx_thread_irq_nesting_end
+@ since it will never be called 16-bit mode. */
+@
+ .arm
+ .text
+ .align 2
+@/**************************************************************************/
+@/* */
+@/* FUNCTION RELEASE */
+@/* */
+@/* _tx_thread_irq_nesting_end Cortex-R52/GNU */
+@/* 6.5.2 */
+@/* AUTHOR */
+@/* */
+@/* Frédéric Desbiens, Eclipse Foundation */
+@/* */
+@/* Derived from the Cortex-R5/GNU port originally written by */
+@/* William E. Lamie, Microsoft Corporation. */
+@/* */
+@/* DESCRIPTION */
+@/* */
+@/* This function is called by the application from IRQ mode after */
+@/* _tx_thread_irq_nesting_start has been called and switches the IRQ */
+@/* processing from system mode back to IRQ mode prior to the ISR */
+@/* calling _tx_thread_context_restore. Note that this function */
+@/* assumes the system stack pointer is in the same position after */
+@/* nesting start function was called. */
+@/* */
+@/* This function assumes that the system mode stack pointer was setup */
+@/* during low-level initialization (tx_initialize_low_level.s). */
+@/* */
+@/* This function returns with IRQ interrupts disabled. */
+@/* */
+@/* INPUT */
+@/* */
+@/* None */
+@/* */
+@/* OUTPUT */
+@/* */
+@/* None */
+@/* */
+@/* CALLS */
+@/* */
+@/* None */
+@/* */
+@/* CALLED BY */
+@/* */
+@/* ISRs */
+@/* */
+@/**************************************************************************/
+@VOID _tx_thread_irq_nesting_end(VOID)
+@{
+ .global _tx_thread_irq_nesting_end
+ .type _tx_thread_irq_nesting_end,function
+_tx_thread_irq_nesting_end:
+ MOV r3,lr @ Save ISR return address
+ MRS r0, CPSR @ Pickup the CPSR
+ ORR r0, r0, #DISABLE_INTS @ Build disable interrupt value
+ MSR CPSR_c, r0 @ Disable interrupts
+ LDMIA sp!, {r1, lr} @ Pickup saved lr (and r1 throw-away for
+ @ 8-byte alignment logic)
+ BIC r0, r0, #MODE_MASK @ Clear mode bits
+ ORR r0, r0, #IRQ_MODE_BITS @ Build IRQ mode CPSR
+ MSR CPSR_c, r0 @ Reenter IRQ mode
+#ifdef __THUMB_INTERWORK
+ BX r3 @ Return to caller
+#else
+ MOV pc, r3 @ Return to caller
+#endif
+@}
+
diff --git a/ports/cortex_r52/gnu/src/tx_thread_irq_nesting_start.S b/ports/cortex_r52/gnu/src/tx_thread_irq_nesting_start.S
new file mode 100644
index 00000000..e300a5be
--- /dev/null
+++ b/ports/cortex_r52/gnu/src/tx_thread_irq_nesting_start.S
@@ -0,0 +1,99 @@
+@/***************************************************************************
+@ * Copyright (c) 2024 Microsoft Corporation
+@ * Copyright (c) 2026 Eclipse ThreadX contributors
+@ *
+@ * This program and the accompanying materials are made available under the
+@ * terms of the MIT License which is available at
+@ * https://opensource.org/licenses/MIT.
+@ *
+@ * SPDX-License-Identifier: MIT
+@ **************************************************************************/
+@ Portions of this file were generated with AI assistance.
+@
+@
+@/**************************************************************************/
+@/**************************************************************************/
+@/** */
+@/** ThreadX Component */
+@/** */
+@/** Thread */
+@/** */
+@/**************************************************************************/
+@/**************************************************************************/
+#ifdef TX_INCLUDE_USER_DEFINE_FILE
+#include "tx_user.h"
+#endif
+
+IRQ_DISABLE = 0x80 @ IRQ disable bit
+MODE_MASK = 0x1F @ Mode mask
+SYS_MODE_BITS = 0x1F @ System mode bits
+@
+@
+@/* No 16-bit Thumb mode veneer code is needed for _tx_thread_irq_nesting_start
+@ since it will never be called 16-bit mode. */
+@
+ .arm
+ .text
+ .align 2
+@/**************************************************************************/
+@/* */
+@/* FUNCTION RELEASE */
+@/* */
+@/* _tx_thread_irq_nesting_start Cortex-R52/GNU */
+@/* 6.5.2 */
+@/* AUTHOR */
+@/* */
+@/* Frédéric Desbiens, Eclipse Foundation */
+@/* */
+@/* Derived from the Cortex-R5/GNU port originally written by */
+@/* William E. Lamie, Microsoft Corporation. */
+@/* */
+@/* DESCRIPTION */
+@/* */
+@/* This function is called by the application from IRQ mode after */
+@/* _tx_thread_context_save has been called and switches the IRQ */
+@/* processing to the system mode so nested IRQ interrupt processing */
+@/* is possible (system mode has its own "lr" register). Note that */
+@/* this function assumes that the system mode stack pointer was setup */
+@/* during low-level initialization (tx_initialize_low_level.s). */
+@/* */
+@/* This function returns with IRQ interrupts enabled. */
+@/* */
+@/* INPUT */
+@/* */
+@/* None */
+@/* */
+@/* OUTPUT */
+@/* */
+@/* None */
+@/* */
+@/* CALLS */
+@/* */
+@/* None */
+@/* */
+@/* CALLED BY */
+@/* */
+@/* ISRs */
+@/* */
+@/**************************************************************************/
+@VOID _tx_thread_irq_nesting_start(VOID)
+@{
+ .global _tx_thread_irq_nesting_start
+ .type _tx_thread_irq_nesting_start,function
+_tx_thread_irq_nesting_start:
+ MOV r3,lr @ Save ISR return address
+ MRS r0, CPSR @ Pickup the CPSR
+ BIC r0, r0, #MODE_MASK @ Clear the mode bits
+ ORR r0, r0, #SYS_MODE_BITS @ Build system mode CPSR
+ MSR CPSR_c, r0 @ Enter system mode
+ STMDB sp!, {r1, lr} @ Push the system mode lr on the system mode stack
+ @ and push r1 just to keep 8-byte alignment
+ BIC r0, r0, #IRQ_DISABLE @ Build enable IRQ CPSR
+ MSR CPSR_c, r0 @ Enter system mode
+#ifdef __THUMB_INTERWORK
+ BX r3 @ Return to caller
+#else
+ MOV pc, r3 @ Return to caller
+#endif
+@}
+
diff --git a/ports/cortex_r52/gnu/src/tx_thread_schedule.S b/ports/cortex_r52/gnu/src/tx_thread_schedule.S
new file mode 100644
index 00000000..2dfc1da7
--- /dev/null
+++ b/ports/cortex_r52/gnu/src/tx_thread_schedule.S
@@ -0,0 +1,240 @@
+@/***************************************************************************
+@ * Copyright (c) 2024 Microsoft Corporation
+@ * Copyright (c) 2026 Eclipse ThreadX contributors
+@ *
+@ * This program and the accompanying materials are made available under the
+@ * terms of the MIT License which is available at
+@ * https://opensource.org/licenses/MIT.
+@ *
+@ * SPDX-License-Identifier: MIT
+@ **************************************************************************/
+@ Portions of this file were generated with AI assistance.
+@
+@
+@/**************************************************************************/
+@/**************************************************************************/
+@/** */
+@/** ThreadX Component */
+@/** */
+@/** Thread */
+@/** */
+@/**************************************************************************/
+@/**************************************************************************/
+#ifdef TX_INCLUDE_USER_DEFINE_FILE
+#include "tx_user.h"
+#endif
+
+ .global _tx_thread_execute_ptr
+ .global _tx_thread_current_ptr
+ .global _tx_timer_time_slice
+ .global _tx_execution_thread_enter
+@
+@
+@/* Define the 16-bit Thumb mode veneer for _tx_thread_schedule for
+@ applications calling this function from to 16-bit Thumb mode. */
+@
+ .text
+ .align 2
+ .global $_tx_thread_schedule
+ .type $_tx_thread_schedule,function
+$_tx_thread_schedule:
+ .thumb
+ BX pc @ Switch to 32-bit mode
+ NOP @
+ .arm
+ STMFD sp!, {lr} @ Save return address
+ BL _tx_thread_schedule @ Call _tx_thread_schedule function
+ LDMFD sp!, {lr} @ Recover saved return address
+ BX lr @ Return to 16-bit caller
+@
+@
+ .text
+ .align 2
+@/**************************************************************************/
+@/* */
+@/* FUNCTION RELEASE */
+@/* */
+@/* _tx_thread_schedule Cortex-R52/GNU */
+@/* 6.5.2 */
+@/* AUTHOR */
+@/* */
+@/* Frédéric Desbiens, Eclipse Foundation */
+@/* */
+@/* Derived from the Cortex-R5/GNU port originally written by */
+@/* William E. Lamie, Microsoft Corporation. */
+@/* */
+@/* DESCRIPTION */
+@/* */
+@/* This function waits for a thread control block pointer to appear in */
+@/* the _tx_thread_execute_ptr variable. Once a thread pointer appears */
+@/* in the variable, the corresponding thread is resumed. */
+@/* */
+@/* INPUT */
+@/* */
+@/* None */
+@/* */
+@/* OUTPUT */
+@/* */
+@/* None */
+@/* */
+@/* CALLS */
+@/* */
+@/* None */
+@/* */
+@/* CALLED BY */
+@/* */
+@/* _tx_initialize_kernel_enter ThreadX entry function */
+@/* _tx_thread_system_return Return to system from thread */
+@/* _tx_thread_context_restore Restore thread's context */
+@/* */
+@/**************************************************************************/
+@VOID _tx_thread_schedule(VOID)
+@{
+ .global _tx_thread_schedule
+ .type _tx_thread_schedule,function
+_tx_thread_schedule:
+@
+@ /* Enable interrupts. */
+@
+#ifdef TX_ENABLE_FIQ_SUPPORT
+ CPSIE if @ Enable IRQ and FIQ interrupts
+#else
+ CPSIE i @ Enable IRQ interrupts
+#endif
+@
+@ /* Wait for a thread to execute. */
+@ do
+@ {
+ LDR r1, =_tx_thread_execute_ptr @ Address of thread execute ptr
+@
+__tx_thread_schedule_loop:
+@
+ LDR r0, [r1] @ Pickup next thread to execute
+ CMP r0, #0 @ Is it NULL?
+ BEQ __tx_thread_schedule_loop @ If so, keep looking for a thread
+@
+@ }
+@ while(_tx_thread_execute_ptr == TX_NULL);
+@
+@ /* Yes! We have a thread to execute. Lockout interrupts and
+@ transfer control to it. */
+@
+#ifdef TX_ENABLE_FIQ_SUPPORT
+ CPSID if @ Disable IRQ and FIQ interrupts
+#else
+ CPSID i @ Disable IRQ interrupts
+#endif
+@
+@ /* Setup the current thread pointer. */
+@ _tx_thread_current_ptr = _tx_thread_execute_ptr;
+@
+ LDR r1, =_tx_thread_current_ptr @ Pickup address of current thread
+ STR r0, [r1] @ Setup current thread pointer
+@
+@ /* Increment the run count for this thread. */
+@ _tx_thread_current_ptr -> tx_thread_run_count++;
+@
+ LDR r2, [r0, #4] @ Pickup run counter
+ LDR r3, [r0, #24] @ Pickup time-slice for this thread
+ ADD r2, r2, #1 @ Increment thread run-counter
+ STR r2, [r0, #4] @ Store the new run counter
+@
+@ /* Setup time-slice, if present. */
+@ _tx_timer_time_slice = _tx_thread_current_ptr -> tx_thread_time_slice;
+@
+ LDR r2, =_tx_timer_time_slice @ Pickup address of time-slice
+ @ variable
+ LDR sp, [r0, #8] @ Switch stack pointers
+ STR r3, [r2] @ Setup time-slice
+@
+@ /* Switch to the thread's stack. */
+@ sp = _tx_thread_execute_ptr -> tx_thread_stack_ptr;
+@
+#ifdef TX_ENABLE_EXECUTION_CHANGE_NOTIFY
+@
+@ /* Call the thread entry function to indicate the thread is executing. */
+@
+ BL _tx_execution_thread_enter @ Call the thread execution enter function
+#endif
+@
+@ /* Determine if an interrupt frame or a synchronous task suspension frame
+@ is present. */
+@
+ LDMIA sp!, {r4, r5} @ Pickup the stack type and saved CPSR
+ CMP r4, #0 @ Check for synchronous context switch
+ BEQ _tx_solicited_return
+ MSR SPSR_cxsf, r5 @ Setup SPSR for return
+#ifdef TX_ENABLE_VFP_SUPPORT
+ LDR r1, [r0, #144] @ Pickup the VFP enabled flag
+ CMP r1, #0 @ Is the VFP enabled?
+ BEQ _tx_skip_interrupt_vfp_restore @ No, skip VFP interrupt restore
+ VLDMIA sp!, {D0-D15} @ Recover D0-D15
+ LDR r4, [sp], #4 @ Pickup FPSCR
+ VMSR FPSCR, r4 @ Restore FPSCR
+_tx_skip_interrupt_vfp_restore:
+#endif
+ LDMIA sp!, {r0-r12, lr, pc}^ @ Return to point of thread interrupt
+@
+_tx_solicited_return:
+#ifdef TX_ENABLE_VFP_SUPPORT
+ LDR r1, [r0, #144] @ Pickup the VFP enabled flag
+ CMP r1, #0 @ Is the VFP enabled?
+ BEQ _tx_skip_solicited_vfp_restore @ No, skip VFP solicited restore
+ VLDMIA sp!, {D8-D15} @ Recover D8-D15
+ LDR r4, [sp], #4 @ Pickup FPSCR
+ VMSR FPSCR, r4 @ Restore FPSCR
+_tx_skip_solicited_vfp_restore:
+#endif
+ MOV r0, r5 @ Move CPSR to scratch register
+ LDMIA sp!, {r4-r11, lr} @ Return to thread synchronously
+ MSR CPSR_cxsf, r0 @ Recover CPSR
+@
+#ifdef __THUMB_INTERWORK
+ BX lr @ Return to caller
+#else
+ MOV pc, lr @ Return to caller
+#endif
+@
+@}
+@
+@
+#ifdef TX_ENABLE_VFP_SUPPORT
+ .global tx_thread_vfp_enable
+ .type tx_thread_vfp_enable,function
+tx_thread_vfp_enable:
+ MRS r2, CPSR @ Pickup the CPSR
+#ifdef TX_ENABLE_FIQ_SUPPORT
+ CPSID if @ Disable IRQ and FIQ interrupts
+#else
+ CPSID i @ Disable IRQ interrupts
+#endif
+ LDR r0, =_tx_thread_current_ptr @ Build current thread pointer address
+ LDR r1, [r0] @ Pickup current thread pointer
+ CMP r1, #0 @ Check for NULL thread pointer
+ BEQ __tx_no_thread_to_enable @ If NULL, skip VFP enable
+ MOV r0, #1 @ Build enable value
+ STR r0, [r1, #144] @ Set the VFP enable flag (tx_thread_vfp_enable field in TX_THREAD)
+__tx_no_thread_to_enable:
+ MSR CPSR_cxsf, r2 @ Recover CPSR
+ BX LR @ Return to caller
+@
+ .global tx_thread_vfp_disable
+ .type tx_thread_vfp_disable,function
+tx_thread_vfp_disable:
+ MRS r2, CPSR @ Pickup the CPSR
+#ifdef TX_ENABLE_FIQ_SUPPORT
+ CPSID if @ Disable IRQ and FIQ interrupts
+#else
+ CPSID i @ Disable IRQ interrupts
+#endif
+ LDR r0, =_tx_thread_current_ptr @ Build current thread pointer address
+ LDR r1, [r0] @ Pickup current thread pointer
+ CMP r1, #0 @ Check for NULL thread pointer
+ BEQ __tx_no_thread_to_disable @ If NULL, skip VFP disable
+ MOV r0, #0 @ Build disable value
+ STR r0, [r1, #144] @ Clear the VFP enable flag (tx_thread_vfp_enable field in TX_THREAD)
+__tx_no_thread_to_disable:
+ MSR CPSR_cxsf, r2 @ Recover CPSR
+ BX LR @ Return to caller
+#endif
+
diff --git a/ports/cortex_r52/gnu/src/tx_thread_stack_build.S b/ports/cortex_r52/gnu/src/tx_thread_stack_build.S
new file mode 100644
index 00000000..1be3b5f3
--- /dev/null
+++ b/ports/cortex_r52/gnu/src/tx_thread_stack_build.S
@@ -0,0 +1,170 @@
+@/***************************************************************************
+@ * Copyright (c) 2024 Microsoft Corporation
+@ * Copyright (c) 2026 Eclipse ThreadX contributors
+@ *
+@ * This program and the accompanying materials are made available under the
+@ * terms of the MIT License which is available at
+@ * https://opensource.org/licenses/MIT.
+@ *
+@ * SPDX-License-Identifier: MIT
+@ **************************************************************************/
+@ Portions of this file were generated with AI assistance.
+@
+@
+@/**************************************************************************/
+@/**************************************************************************/
+@/** */
+@/** ThreadX Component */
+@/** */
+@/** Thread */
+@/** */
+@/**************************************************************************/
+@/**************************************************************************/
+#ifdef TX_INCLUDE_USER_DEFINE_FILE
+#include "tx_user.h"
+#endif
+
+ .arm
+
+SVC_MODE = 0x13 @ SVC mode
+#ifdef TX_ENABLE_FIQ_SUPPORT
+CPSR_MASK = 0xDF @ Mask initial CPSR, IRQ & FIQ interrupts enabled
+#else
+CPSR_MASK = 0x9F @ Mask initial CPSR, IRQ interrupts enabled
+#endif
+@
+@
+@/* Define the 16-bit Thumb mode veneer for _tx_thread_stack_build for
+@ applications calling this function from to 16-bit Thumb mode. */
+@
+ .text
+ .align 2
+ .thumb
+ .global $_tx_thread_stack_build
+ .type $_tx_thread_stack_build,function
+$_tx_thread_stack_build:
+ BX pc @ Switch to 32-bit mode
+ NOP @
+ .arm
+ STMFD sp!, {lr} @ Save return address
+ BL _tx_thread_stack_build @ Call _tx_thread_stack_build function
+ LDMFD sp!, {lr} @ Recover saved return address
+ BX lr @ Return to 16-bit caller
+@
+@
+ .text
+ .align 2
+@/**************************************************************************/
+@/* */
+@/* FUNCTION RELEASE */
+@/* */
+@/* _tx_thread_stack_build Cortex-R52/GNU */
+@/* 6.5.2 */
+@/* AUTHOR */
+@/* */
+@/* Frédéric Desbiens, Eclipse Foundation */
+@/* */
+@/* Derived from the Cortex-R5/GNU port originally written by */
+@/* William E. Lamie, Microsoft Corporation. */
+@/* */
+@/* DESCRIPTION */
+@/* */
+@/* This function builds a stack frame on the supplied thread's stack. */
+@/* The stack frame results in a fake interrupt return to the supplied */
+@/* function pointer. */
+@/* */
+@/* INPUT */
+@/* */
+@/* thread_ptr Pointer to thread control blk */
+@/* function_ptr Pointer to return function */
+@/* */
+@/* OUTPUT */
+@/* */
+@/* None */
+@/* */
+@/* CALLS */
+@/* */
+@/* None */
+@/* */
+@/* CALLED BY */
+@/* */
+@/* _tx_thread_create Create thread service */
+@/* */
+@/**************************************************************************/
+@VOID _tx_thread_stack_build(TX_THREAD *thread_ptr, VOID (*function_ptr)(VOID))
+@{
+ .global _tx_thread_stack_build
+ .type _tx_thread_stack_build,function
+_tx_thread_stack_build:
+@
+@
+@ /* Build a fake interrupt frame. The form of the fake interrupt stack
+@ on the ARM9 should look like the following after it is built:
+@
+@ Stack Top: 1 Interrupt stack frame type
+@ CPSR Initial value for CPSR
+@ a1 (r0) Initial value for a1
+@ a2 (r1) Initial value for a2
+@ a3 (r2) Initial value for a3
+@ a4 (r3) Initial value for a4
+@ v1 (r4) Initial value for v1
+@ v2 (r5) Initial value for v2
+@ v3 (r6) Initial value for v3
+@ v4 (r7) Initial value for v4
+@ v5 (r8) Initial value for v5
+@ sb (r9) Initial value for sb
+@ sl (r10) Initial value for sl
+@ fp (r11) Initial value for fp
+@ ip (r12) Initial value for ip
+@ lr (r14) Initial value for lr
+@ pc (r15) Initial value for pc
+@ 0 For stack backtracing
+@
+@ Stack Bottom: (higher memory address) */
+@
+ LDR r2, [r0, #16] @ Pickup end of stack area
+ BIC r2, r2, #7 @ Ensure 8-byte alignment
+ SUB r2, r2, #76 @ Allocate space for the stack frame
+@
+@ /* Actually build the stack frame. */
+@
+ MOV r3, #1 @ Build interrupt stack type
+ STR r3, [r2, #0] @ Store stack type
+ MOV r3, #0 @ Build initial register value
+ STR r3, [r2, #8] @ Store initial r0
+ STR r3, [r2, #12] @ Store initial r1
+ STR r3, [r2, #16] @ Store initial r2
+ STR r3, [r2, #20] @ Store initial r3
+ STR r3, [r2, #24] @ Store initial r4
+ STR r3, [r2, #28] @ Store initial r5
+ STR r3, [r2, #32] @ Store initial r6
+ STR r3, [r2, #36] @ Store initial r7
+ STR r3, [r2, #40] @ Store initial r8
+ STR r3, [r2, #44] @ Store initial r9
+ LDR r3, [r0, #12] @ Pickup stack starting address
+ STR r3, [r2, #48] @ Store initial r10 (sl)
+ LDR r3,=_tx_thread_schedule @ Pickup address of _tx_thread_schedule for GDB backtrace
+ STR r3, [r2, #60] @ Store initial r14 (lr)
+ MOV r3, #0 @ Build initial register value
+ STR r3, [r2, #52] @ Store initial r11
+ STR r3, [r2, #56] @ Store initial r12
+ STR r1, [r2, #64] @ Store initial pc
+ STR r3, [r2, #68] @ 0 for back-trace
+ MRS r1, CPSR @ Pickup CPSR
+ BIC r1, r1, #CPSR_MASK @ Mask mode bits of CPSR
+ ORR r3, r1, #SVC_MODE @ Build CPSR, SVC mode, interrupts enabled
+ STR r3, [r2, #4] @ Store initial CPSR
+@
+@ /* Setup stack pointer. */
+@ thread_ptr -> tx_thread_stack_ptr = r2;
+@
+ STR r2, [r0, #8] @ Save stack pointer in thread's
+ @ control block
+#ifdef __THUMB_INTERWORK
+ BX lr @ Return to caller
+#else
+ MOV pc, lr @ Return to caller
+#endif
+@}
+
+
diff --git a/ports/cortex_r52/gnu/src/tx_thread_system_return.S b/ports/cortex_r52/gnu/src/tx_thread_system_return.S
new file mode 100644
index 00000000..ae0eac7d
--- /dev/null
+++ b/ports/cortex_r52/gnu/src/tx_thread_system_return.S
@@ -0,0 +1,169 @@
+@/***************************************************************************
+@ * Copyright (c) 2024 Microsoft Corporation
+@ * Copyright (c) 2026 Eclipse ThreadX contributors
+@ *
+@ * This program and the accompanying materials are made available under the
+@ * terms of the MIT License which is available at
+@ * https://opensource.org/licenses/MIT.
+@ *
+@ * SPDX-License-Identifier: MIT
+@ **************************************************************************/
+@ Portions of this file were generated with AI assistance.
+@
+@
+@/**************************************************************************/
+@/**************************************************************************/
+@/** */
+@/** ThreadX Component */
+@/** */
+@/** Thread */
+@/** */
+@/**************************************************************************/
+@/**************************************************************************/
+#ifdef TX_INCLUDE_USER_DEFINE_FILE
+#include "tx_user.h"
+#endif
+
+ .arm
+@
+@
+ .global _tx_thread_current_ptr
+ .global _tx_timer_time_slice
+ .global _tx_thread_schedule
+ .global _tx_execution_thread_exit
+@
+@
+@
+@/* Define the 16-bit Thumb mode veneer for _tx_thread_system_return for
+@ applications calling this function from to 16-bit Thumb mode. */
+@
+ .text
+ .align 2
+ .global $_tx_thread_system_return
+ .type $_tx_thread_system_return,function
+$_tx_thread_system_return:
+ .thumb
+ BX pc @ Switch to 32-bit mode
+ NOP @
+ .arm
+ STMFD sp!, {lr} @ Save return address
+ BL _tx_thread_system_return @ Call _tx_thread_system_return function
+ LDMFD sp!, {lr} @ Recover saved return address
+ BX lr @ Return to 16-bit caller
+@
+@
+ .text
+ .align 2
+@/**************************************************************************/
+@/* */
+@/* FUNCTION RELEASE */
+@/* */
+@/* _tx_thread_system_return Cortex-R52/GNU */
+@/* 6.5.2 */
+@/* AUTHOR */
+@/* */
+@/* Frédéric Desbiens, Eclipse Foundation */
+@/* */
+@/* Derived from the Cortex-R5/GNU port originally written by */
+@/* William E. Lamie, Microsoft Corporation. */
+@/* */
+@/* DESCRIPTION */
+@/* */
+@/* This function is target processor specific. It is used to transfer */
+@/* control from a thread back to the ThreadX system. Only a */
+@/* minimal context is saved since the compiler assumes temp registers */
+@/* are going to get slicked by a function call anyway. */
+@/* */
+@/* INPUT */
+@/* */
+@/* None */
+@/* */
+@/* OUTPUT */
+@/* */
+@/* None */
+@/* */
+@/* CALLS */
+@/* */
+@/* _tx_thread_schedule Thread scheduling loop */
+@/* */
+@/* CALLED BY */
+@/* */
+@/* ThreadX components */
+@/* */
+@/**************************************************************************/
+@VOID _tx_thread_system_return(VOID)
+@{
+ .global _tx_thread_system_return
+ .type _tx_thread_system_return,function
+_tx_thread_system_return:
+@
+@ /* Lockout interrupts. */
+@
+ MRS r1, CPSR @ Pickup the CPSR
+#ifdef TX_ENABLE_FIQ_SUPPORT
+ CPSID if @ Disable IRQ and FIQ interrupts
+#else
+ CPSID i @ Disable IRQ interrupts
+#endif
+@ /* Save minimal context on the stack. */
+@
+ STMDB sp!, {r4-r11, lr} @ Save minimal context
+ LDR r5, =_tx_thread_current_ptr @ Pickup address of current ptr
+ LDR r6, [r5, #0] @ Pickup current thread pointer
+@
+#ifdef TX_ENABLE_VFP_SUPPORT
+ LDR r0, [r6, #144] @ Pickup the VFP enabled flag
+ CMP r0, #0 @ Is the VFP enabled?
+ BEQ _tx_skip_solicited_vfp_save @ No, skip VFP solicited save
+ VMRS r4, FPSCR @ Pickup the FPSCR
+ STR r4, [sp, #-4]! @ Save FPSCR
+ VSTMDB sp!, {D8-D15} @ Save D8-D15
+_tx_skip_solicited_vfp_save:
+#endif
+@
+ MOV r0, #0 @ Build a solicited stack type
+ STMDB sp!, {r0-r1} @ Save type and CPSR
+@
+@
+#ifdef TX_ENABLE_EXECUTION_CHANGE_NOTIFY
+@
+@ /* Call the thread exit function to indicate the thread is no longer executing. */
+@
+ BL _tx_execution_thread_exit @ Call the thread exit function
+#endif
+@
+ LDR r2, =_tx_timer_time_slice @ Pickup address of time slice
+ LDR r1, [r2, #0] @ Pickup current time slice
+@
+@ /* Save current stack and switch to system stack. */
+@ _tx_thread_current_ptr -> tx_thread_stack_ptr = sp;
+@ sp = _tx_thread_system_stack_ptr;
+@
+ STR sp, [r6, #8] @ Save thread stack pointer
+@
+@ /* Determine if the time-slice is active. */
+@ if (_tx_timer_time_slice)
+@ {
+@
+ MOV r4, #0 @ Build clear value
+ CMP r1, #0 @ Is a time-slice active?
+ BEQ __tx_thread_dont_save_ts @ No, don't save the time-slice
+@
+@ /* Save time-slice for the thread and clear the current time-slice. */
+@ _tx_thread_current_ptr -> tx_thread_time_slice = _tx_timer_time_slice;
+@ _tx_timer_time_slice = 0;
+@
+ STR r4, [r2, #0] @ Clear time-slice
+ STR r1, [r6, #24] @ Save current time-slice
+@
+@ }
+__tx_thread_dont_save_ts:
+@
+@ /* Clear the current thread pointer. */
+@ _tx_thread_current_ptr = TX_NULL;
+@
+ STR r4, [r5, #0] @ Clear current thread pointer
+ B _tx_thread_schedule @ Jump to scheduler!
+@
+@}
+
diff --git a/ports/cortex_r52/gnu/src/tx_thread_vectored_context_save.S b/ports/cortex_r52/gnu/src/tx_thread_vectored_context_save.S
new file mode 100644
index 00000000..60eeca7b
--- /dev/null
+++ b/ports/cortex_r52/gnu/src/tx_thread_vectored_context_save.S
@@ -0,0 +1,181 @@
+@/***************************************************************************
+@ * Copyright (c) 2024 Microsoft Corporation
+@ * Copyright (c) 2026 Eclipse ThreadX contributors
+@ *
+@ * This program and the accompanying materials are made available under the
+@ * terms of the MIT License which is available at
+@ * https://opensource.org/licenses/MIT.
+@ *
+@ * SPDX-License-Identifier: MIT
+@ **************************************************************************/
+@ Portions of this file were generated with AI assistance.
+@
+@
+@/**************************************************************************/
+@/**************************************************************************/
+@/** */
+@/** ThreadX Component */
+@/** */
+@/** Thread */
+@/** */
+@/**************************************************************************/
+@/**************************************************************************/
+#ifdef TX_INCLUDE_USER_DEFINE_FILE
+#include "tx_user.h"
+#endif
+
+ .global _tx_thread_system_state
+ .global _tx_thread_current_ptr
+ .global _tx_execution_isr_enter
+@
+@
+@
+@/* No 16-bit Thumb mode veneer code is needed for _tx_thread_vectored_context_save
+@ since it will never be called 16-bit mode. */
+@
+ .arm
+ .text
+ .align 2
+@/**************************************************************************/
+@/* */
+@/* FUNCTION RELEASE */
+@/* */
+@/* _tx_thread_vectored_context_save Cortex-R52/GNU */
+@/* 6.5.2 */
+@/* AUTHOR */
+@/* */
+@/* Frédéric Desbiens, Eclipse Foundation */
+@/* */
+@/* Derived from the Cortex-R5/GNU port originally written by */
+@/* William E. Lamie, Microsoft Corporation. */
+@/* */
+@/* DESCRIPTION */
+@/* */
+@/* This function saves the context of an executing thread in the */
+@/* beginning of interrupt processing. The function also ensures that */
+@/* the system stack is used upon return to the calling ISR. */
+@/* */
+@/* INPUT */
+@/* */
+@/* None */
+@/* */
+@/* OUTPUT */
+@/* */
+@/* None */
+@/* */
+@/* CALLS */
+@/* */
+@/* None */
+@/* */
+@/* CALLED BY */
+@/* */
+@/* ISRs */
+@/* */
+@/**************************************************************************/
+@VOID _tx_thread_vectored_context_save(VOID)
+@{
+ .global _tx_thread_vectored_context_save
+ .type _tx_thread_vectored_context_save,function
+_tx_thread_vectored_context_save:
+@
+@ /* Upon entry to this routine, it is assumed that IRQ interrupts are locked
+@ out, we are in IRQ mode, and all registers are intact. */
+@
+@ /* Check for a nested interrupt condition. */
+@ if (_tx_thread_system_state++)
+@ {
+@
+#ifdef TX_ENABLE_FIQ_SUPPORT
+ CPSID if @ Disable IRQ and FIQ interrupts
+#endif
+ LDR r3, =_tx_thread_system_state @ Pickup address of system state variable
+ LDR r2, [r3, #0] @ Pickup system state
+ CMP r2, #0 @ Is this the first interrupt?
+ BEQ __tx_thread_not_nested_save @ Yes, not a nested context save
+@
+@ /* Nested interrupt condition. */
+@
+ ADD r2, r2, #1 @ Increment the interrupt counter
+ STR r2, [r3, #0] @ Store it back in the variable
+@
+@ /* Note: Minimal context of interrupted thread is already saved. */
+@
+@ /* Return to the ISR. */
+@
+ MOV r10, #0 @ Clear stack limit
+
+#ifdef TX_ENABLE_EXECUTION_CHANGE_NOTIFY
+@
+@ /* Call the ISR enter function to indicate an ISR is executing. */
+@
+ PUSH {lr} @ Save ISR lr
+ BL _tx_execution_isr_enter @ Call the ISR enter function
+ POP {lr} @ Recover ISR lr
+#endif
+
+ MOV pc, lr @ Return to caller
+@
+__tx_thread_not_nested_save:
+@ }
+@
+@ /* Otherwise, not nested, check to see if a thread was running. */
+@ else if (_tx_thread_current_ptr)
+@ {
+@
+ ADD r2, r2, #1 @ Increment the interrupt counter
+ STR r2, [r3, #0] @ Store it back in the variable
+ LDR r1, =_tx_thread_current_ptr @ Pickup address of current thread ptr
+ LDR r0, [r1, #0] @ Pickup current thread pointer
+ CMP r0, #0 @ Is it NULL?
+ BEQ __tx_thread_idle_system_save @ If so, interrupt occurred in
+ @ scheduling loop - nothing needs saving!
+@
+@ /* Note: Minimal context of interrupted thread is already saved. */
+@
+@ /* Save the current stack pointer in the thread's control block. */
+@ _tx_thread_current_ptr -> tx_thread_stack_ptr = sp;
+@
+@ /* Switch to the system stack. */
+@ sp = _tx_thread_system_stack_ptr;
+@
+ MOV r10, #0 @ Clear stack limit
+
+#ifdef TX_ENABLE_EXECUTION_CHANGE_NOTIFY
+@
+@ /* Call the ISR enter function to indicate an ISR is executing. */
+@
+ PUSH {lr} @ Save ISR lr
+ BL _tx_execution_isr_enter @ Call the ISR enter function
+ POP {lr} @ Recover ISR lr
+#endif
+
+ MOV pc, lr @ Return to caller
+@
+@ }
+@ else
+@ {
+@
+__tx_thread_idle_system_save:
+@
+@ /* Interrupt occurred in the scheduling loop. */
+@
+@ /* Not much to do here, just adjust the stack pointer, and return to IRQ
+@ processing. */
+@
+ MOV r10, #0 @ Clear stack limit
+
+#ifdef TX_ENABLE_EXECUTION_CHANGE_NOTIFY
+@
+@ /* Call the ISR enter function to indicate an ISR is executing. */
+@
+ PUSH {lr} @ Save ISR lr
+ BL _tx_execution_isr_enter @ Call the ISR enter function
+ POP {lr} @ Recover ISR lr
+#endif
+
+ ADD sp, sp, #32 @ Recover saved registers
+ MOV pc, lr @ Return to caller
+@
+@ }
+@}
+
diff --git a/ports/cortex_r52/gnu/src/tx_timer_interrupt.S b/ports/cortex_r52/gnu/src/tx_timer_interrupt.S
new file mode 100644
index 00000000..e70a4d02
--- /dev/null
+++ b/ports/cortex_r52/gnu/src/tx_timer_interrupt.S
@@ -0,0 +1,270 @@
+@/***************************************************************************
+@ * Copyright (c) 2024 Microsoft Corporation
+@ * Copyright (c) 2026 Eclipse ThreadX contributors
+@ *
+@ * This program and the accompanying materials are made available under the
+@ * terms of the MIT License which is available at
+@ * https://opensource.org/licenses/MIT.
+@ *
+@ * SPDX-License-Identifier: MIT
+@ **************************************************************************/
+@ Portions of this file were generated with AI assistance.
+@
+@
+@/**************************************************************************/
+@/**************************************************************************/
+@/** */
+@/** ThreadX Component */
+@/** */
+@/** Timer */
+@/** */
+@/**************************************************************************/
+@/**************************************************************************/
+#ifdef TX_INCLUDE_USER_DEFINE_FILE
+#include "tx_user.h"
+#endif
+
+ .arm
+
+@
+@/* Define Assembly language external references... */
+@
+ .global _tx_timer_time_slice
+ .global _tx_timer_system_clock
+ .global _tx_timer_current_ptr
+ .global _tx_timer_list_start
+ .global _tx_timer_list_end
+ .global _tx_timer_expired_time_slice
+ .global _tx_timer_expired
+ .global _tx_thread_time_slice
+@
+@
+@
+@/* Define the 16-bit Thumb mode veneer for _tx_timer_interrupt for
+@ applications calling this function from to 16-bit Thumb mode. */
+@
+ .text
+ .align 2
+ .thumb
+ .global $_tx_timer_interrupt
+ .type $_tx_timer_interrupt,function
+$_tx_timer_interrupt:
+ BX pc @ Switch to 32-bit mode
+ NOP @
+ .arm
+ STMFD sp!, {lr} @ Save return address
+ BL _tx_timer_interrupt @ Call _tx_timer_interrupt function
+ LDMFD sp!, {lr} @ Recover saved return address
+ BX lr @ Return to 16-bit caller
+@
+@
+ .text
+ .align 2
+@/**************************************************************************/
+@/* */
+@/* FUNCTION RELEASE */
+@/* */
+@/* _tx_timer_interrupt Cortex-R52/GNU */
+@/* 6.5.2 */
+@/* AUTHOR */
+@/* */
+@/* Frédéric Desbiens, Eclipse Foundation */
+@/* */
+@/* Derived from the Cortex-R5/GNU port originally written by */
+@/* William E. Lamie, Microsoft Corporation. */
+@/* */
+@/* DESCRIPTION */
+@/* */
+@/* This function processes the hardware timer interrupt. This */
+@/* processing includes incrementing the system clock and checking for */
+@/* time slice and/or timer expiration. If either is found, the */
+@/* interrupt context save/restore functions are called along with the */
+@/* expiration functions. */
+@/* */
+@/* INPUT */
+@/* */
+@/* None */
+@/* */
+@/* OUTPUT */
+@/* */
+@/* None */
+@/* */
+@/* CALLS */
+@/* */
+@/* _tx_thread_time_slice Time slice interrupted thread */
+@/* _tx_timer_expiration_process Timer expiration processing */
+@/* */
+@/* CALLED BY */
+@/* */
+@/* interrupt vector */
+@/* */
+@/**************************************************************************/
+@VOID _tx_timer_interrupt(VOID)
+@{
+ .global _tx_timer_interrupt
+ .type _tx_timer_interrupt,function
+_tx_timer_interrupt:
+@
+@ /* Upon entry to this routine, it is assumed that context save has already
+@ been called, and therefore the compiler scratch registers are available
+@ for use. */
+@
+@ /* Increment the system clock. */
+@ _tx_timer_system_clock++;
+@
+ LDR r1, =_tx_timer_system_clock @ Pickup address of system clock
+ LDR r0, [r1] @ Pickup system clock
+ ADD r0, r0, #1 @ Increment system clock
+ STR r0, [r1] @ Store new system clock
+@
+@ /* Test for time-slice expiration. */
+@ if (_tx_timer_time_slice)
+@ {
+@
+ LDR r3, =_tx_timer_time_slice @ Pickup address of time-slice
+ LDR r2, [r3] @ Pickup time-slice
+ CMP r2, #0 @ Is it non-active?
+ BEQ __tx_timer_no_time_slice @ Yes, skip time-slice processing
+@
+@ /* Decrement the time_slice. */
+@ _tx_timer_time_slice--;
+@
+ SUB r2, r2, #1 @ Decrement the time-slice
+ STR r2, [r3] @ Store new time-slice value
+@
+@ /* Check for expiration. */
+@ if (__tx_timer_time_slice == 0)
+@
+ CMP r2, #0 @ Has it expired?
+ BNE __tx_timer_no_time_slice @ No, skip expiration processing
+@
+@ /* Set the time-slice expired flag. */
+@ _tx_timer_expired_time_slice = TX_TRUE;
+@
+ LDR r3, =_tx_timer_expired_time_slice @ Pickup address of expired flag
+ MOV r0, #1 @ Build expired value
+ STR r0, [r3] @ Set time-slice expiration flag
+@
+@ }
+@
+__tx_timer_no_time_slice:
+@
+@ /* Test for timer expiration. */
+@ if (*_tx_timer_current_ptr)
+@ {
+@
+ LDR r1, =_tx_timer_current_ptr @ Pickup current timer pointer address
+ LDR r0, [r1] @ Pickup current timer
+ LDR r2, [r0] @ Pickup timer list entry
+ CMP r2, #0 @ Is there anything in the list?
+ BEQ __tx_timer_no_timer @ No, just increment the timer
+@
+@ /* Set expiration flag. */
+@ _tx_timer_expired = TX_TRUE;
+@
+ LDR r3, =_tx_timer_expired @ Pickup expiration flag address
+ MOV r2, #1 @ Build expired value
+ STR r2, [r3] @ Set expired flag
+ B __tx_timer_done @ Finished timer processing
+@
+@ }
+@ else
+@ {
+__tx_timer_no_timer:
+@
+@ /* No timer expired, increment the timer pointer. */
+@ _tx_timer_current_ptr++;
+@
+ ADD r0, r0, #4 @ Move to next timer
+@
+@ /* Check for wraparound. */
+@ if (_tx_timer_current_ptr == _tx_timer_list_end)
+@
+ LDR r3, =_tx_timer_list_end @ Pickup address of timer list end
+ LDR r2, [r3] @ Pickup list end
+ CMP r0, r2 @ Are we at list end?
+ BNE __tx_timer_skip_wrap @ No, skip wraparound logic
+@
+@ /* Wrap to beginning of list. */
+@ _tx_timer_current_ptr = _tx_timer_list_start;
+@
+ LDR r3, =_tx_timer_list_start @ Pickup address of timer list start
+ LDR r0, [r3] @ Set current pointer to list start
+@
+__tx_timer_skip_wrap:
+@
+ STR r0, [r1] @ Store new current timer pointer
+@ }
+@
+__tx_timer_done:
+@
+@
+@ /* See if anything has expired. */
+@ if ((_tx_timer_expired_time_slice) || (_tx_timer_expired))
+@ {
+@
+ LDR r3, =_tx_timer_expired_time_slice @ Pickup address of expired flag
+ LDR r2, [r3] @ Pickup time-slice expired flag
+ CMP r2, #0 @ Did a time-slice expire?
+ BNE __tx_something_expired @ If non-zero, time-slice expired
+ LDR r1, =_tx_timer_expired @ Pickup address of other expired flag
+ LDR r0, [r1] @ Pickup timer expired flag
+ CMP r0, #0 @ Did a timer expire?
+ BEQ __tx_timer_nothing_expired @ No, nothing expired
+@
+__tx_something_expired:
+@
+@
+ STMDB sp!, {r0, lr} @ Save the lr register on the stack
+ @ and save r0 just to keep 8-byte alignment
+@
+@ /* Did a timer expire? */
+@ if (_tx_timer_expired)
+@ {
+@
+ LDR r1, =_tx_timer_expired @ Pickup address of expired flag
+ LDR r0, [r1] @ Pickup timer expired flag
+ CMP r0, #0 @ Check for timer expiration
+ BEQ __tx_timer_dont_activate @ If not set, skip timer activation
+@
+@ /* Process timer expiration. */
+@ _tx_timer_expiration_process();
+@
+ BL _tx_timer_expiration_process @ Call the timer expiration handling routine
+@
+@ }
+__tx_timer_dont_activate:
+@
+@ /* Did time slice expire? */
+@ if (_tx_timer_expired_time_slice)
+@ {
+@
+ LDR r3, =_tx_timer_expired_time_slice @ Pickup address of time-slice expired
+ LDR r2, [r3] @ Pickup the actual flag
+ CMP r2, #0 @ See if the flag is set
+ BEQ __tx_timer_not_ts_expiration @ No, skip time-slice processing
+@
+@ /* Time slice interrupted thread. */
+@ _tx_thread_time_slice();
+@
+ BL _tx_thread_time_slice @ Call time-slice processing
+@
+@ }
+@
+__tx_timer_not_ts_expiration:
+@
+ LDMIA sp!, {r0, lr} @ Recover lr register (r0 is just there for
+ @ the 8-byte stack alignment
+@
+@ }
+@
+__tx_timer_nothing_expired:
+@
+#ifdef __THUMB_INTERWORK
+ BX lr @ Return to caller
+#else
+ MOV pc, lr @ Return to caller
+#endif
+@
+@}
+