1@/**************************************************************************/
2@/*                                                                        */
3@/*       Copyright (c) Microsoft Corporation. All rights reserved.        */
4@/*                                                                        */
5@/*       This software is licensed under the Microsoft Software License   */
6@/*       Terms for Microsoft Azure RTOS. Full text of the license can be  */
7@/*       found in the LICENSE file at https://aka.ms/AzureRTOS_EULA       */
8@/*       and in the root directory of this software.                      */
9@/*                                                                        */
10@/**************************************************************************/
11@
12@
13@/**************************************************************************/
14@/**************************************************************************/
15@/**                                                                       */
16@/** ThreadX Component                                                     */
17@/**                                                                       */
18@/**   Thread                                                              */
19@/**                                                                       */
20@/**************************************************************************/
21@/**************************************************************************/
22#ifdef TX_INCLUDE_USER_DEFINE_FILE
23#include "tx_user.h"
24#endif
25
26#ifdef TX_ENABLE_FIQ_SUPPORT
27DISABLE_INTS    =       0xC0                    @ IRQ & FIQ interrupts disabled
28#else
29DISABLE_INTS    =       0x80                    @ IRQ interrupts disabled
30#endif
31@
32@
33    .global     _tx_thread_system_state
34    .global     _tx_thread_current_ptr
35    .global     _tx_execution_isr_enter
36@
37@
38@
39@/* No 16-bit Thumb mode veneer code is needed for _tx_thread_vectored_context_save
40@   since it will never be called 16-bit mode.  */
41@
42    .arm
43    .text
44    .align 2
45@/**************************************************************************/
46@/*                                                                        */
47@/*  FUNCTION                                               RELEASE        */
48@/*                                                                        */
49@/*    _tx_thread_vectored_context_save                     ARM9/GNU       */
50@/*                                                           6.2.1        */
51@/*  AUTHOR                                                                */
52@/*                                                                        */
53@/*    William E. Lamie, Microsoft Corporation                             */
54@/*                                                                        */
55@/*  DESCRIPTION                                                           */
56@/*                                                                        */
57@/*    This function saves the context of an executing thread in the       */
58@/*    beginning of interrupt processing.  The function also ensures that  */
59@/*    the system stack is used upon return to the calling ISR.            */
60@/*                                                                        */
61@/*  INPUT                                                                 */
62@/*                                                                        */
63@/*    None                                                                */
64@/*                                                                        */
65@/*  OUTPUT                                                                */
66@/*                                                                        */
67@/*    None                                                                */
68@/*                                                                        */
69@/*  CALLS                                                                 */
70@/*                                                                        */
71@/*    None                                                                */
72@/*                                                                        */
73@/*  CALLED BY                                                             */
74@/*                                                                        */
75@/*    ISRs                                                                */
76@/*                                                                        */
77@/*  RELEASE HISTORY                                                       */
78@/*                                                                        */
79@/*    DATE              NAME                      DESCRIPTION             */
80@/*                                                                        */
81@/*  09-30-2020     William E. Lamie         Initial Version 6.1           */
82@/*  03-08-2023     Cindy Deng               Modified comment(s), added    */
83@/*                                            #include tx_user.h,         */
84@/*                                            resulting in version 6.2.1  */
85@/*                                                                        */
86@/**************************************************************************/
87@VOID  _tx_thread_vectored_context_save(VOID)
88@{
89    .global  _tx_thread_vectored_context_save
90    .type    _tx_thread_vectored_context_save,function
91_tx_thread_vectored_context_save:
92@
93@    /* Upon entry to this routine, it is assumed that IRQ interrupts are locked
94@       out, we are in IRQ mode, and all registers are intact.  */
95@
96@    /* Check for a nested interrupt condition.  */
97@    if (_tx_thread_system_state++)
98@    {
99@
100#ifdef TX_ENABLE_FIQ_SUPPORT
101    MRS     r0, CPSR                            @ Pickup the CPSR
102    ORR     r0, r0, #DISABLE_INTS               @ Build disable interrupt CPSR
103    MSR     CPSR_cxsf, r0                       @ Disable interrupts
104#endif
105    LDR     r3, =_tx_thread_system_state        @ Pickup address of system state variable
106    LDR     r2, [r3, #0]                        @ Pickup system state
107    CMP     r2, #0                              @ Is this the first interrupt?
108    BEQ     __tx_thread_not_nested_save         @ Yes, not a nested context save
109@
110@    /* Nested interrupt condition.  */
111@
112    ADD     r2, r2, #1                          @ Increment the interrupt counter
113    STR     r2, [r3, #0]                        @ Store it back in the variable
114@
115@    /* Note: Minimal context of interrupted thread is already saved.  */
116@
117@    /* Return to the ISR.  */
118@
119    MOV     r10, #0                             @ Clear stack limit
120
121#ifdef TX_ENABLE_EXECUTION_CHANGE_NOTIFY
122@
123@    /* Call the ISR enter function to indicate an ISR is executing.  */
124@
125    PUSH    {lr}                                @ Save ISR lr
126    BL      _tx_execution_isr_enter             @ Call the ISR enter function
127    POP     {lr}                                @ Recover ISR lr
128#endif
129
130    MOV     pc, lr                              @ Return to caller
131@
132__tx_thread_not_nested_save:
133@    }
134@
135@    /* Otherwise, not nested, check to see if a thread was running.  */
136@    else if (_tx_thread_current_ptr)
137@    {
138@
139    ADD     r2, r2, #1                          @ Increment the interrupt counter
140    STR     r2, [r3, #0]                        @ Store it back in the variable
141    LDR     r1, =_tx_thread_current_ptr         @ Pickup address of current thread ptr
142    LDR     r0, [r1, #0]                        @ Pickup current thread pointer
143    CMP     r0, #0                              @ Is it NULL?
144    BEQ     __tx_thread_idle_system_save        @ If so, interrupt occurred in
145                                                @   scheduling loop - nothing needs saving!
146@
147@    /* Note: Minimal context of interrupted thread is already saved.  */
148@
149@    /* Save the current stack pointer in the thread's control block.  */
150@    _tx_thread_current_ptr -> tx_thread_stack_ptr =  sp;
151@
152@    /* Switch to the system stack.  */
153@    sp =  _tx_thread_system_stack_ptr;
154@
155    MOV     r10, #0                             @ Clear stack limit
156
157#ifdef TX_ENABLE_EXECUTION_CHANGE_NOTIFY
158@
159@    /* Call the ISR enter function to indicate an ISR is executing.  */
160@
161    PUSH    {lr}                                @ Save ISR lr
162    BL      _tx_execution_isr_enter             @ Call the ISR enter function
163    POP     {lr}                                @ Recover ISR lr
164#endif
165
166    MOV     pc, lr                              @ Return to caller
167@
168@    }
169@    else
170@    {
171@
172__tx_thread_idle_system_save:
173@
174@    /* Interrupt occurred in the scheduling loop.  */
175@
176@    /* Not much to do here, just adjust the stack pointer, and return to IRQ
177@       processing.  */
178@
179    MOV     r10, #0                             @ Clear stack limit
180
181#ifdef TX_ENABLE_EXECUTION_CHANGE_NOTIFY
182@
183@    /* Call the ISR enter function to indicate an ISR is executing.  */
184@
185    PUSH    {lr}                                @ Save ISR lr
186    BL      _tx_execution_isr_enter             @ Call the ISR enter function
187    POP     {lr}                                @ Recover ISR lr
188#endif
189
190    ADD     sp, sp, #32                         @ Recover saved registers
191    MOV     pc, lr                              @ Return to caller
192@
193@    }
194@}
195
196