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;
23;
24;#define TX_SOURCE_CODE
25;
26;
27;/* Include necessary system files.  */
28;
29;#include "tx_api.h"
30;#include "tx_thread.h"
31;#include "tx_timer.h"
32;
33    .global     __tx_thread_system_state
34    .global     __tx_thread_current_ptr
35    .global     __tx_thread_system_stack_ptr
36
37    .text
38;/**************************************************************************/
39;/*                                                                        */
40;/*  FUNCTION                                               RELEASE        */
41;/*                                                                        */
42;/*    _tx_thread_context_save                              RXv3/GNURX     */
43;/*                                                           6.1.11       */
44;/*  AUTHOR                                                                */
45;/*                                                                        */
46;/*    William E. Lamie, Microsoft Corporation                             */
47;/*                                                                        */
48;/*  DESCRIPTION                                                           */
49;/*                                                                        */
50;/*    This function saves the context of an executing thread in the       */
51;/*    beginning of interrupt processing.  The function also ensures that  */
52;/*    the system stack is used upon return to the calling ISR.            */
53;/*                                                                        */
54;/*  INPUT                                                                 */
55;/*                                                                        */
56;/*    None                                                                */
57;/*                                                                        */
58;/*  OUTPUT                                                                */
59;/*                                                                        */
60;/*    None                                                                */
61;/*                                                                        */
62;/*  CALLS                                                                 */
63;/*                                                                        */
64;/*    None                                                                */
65;/*                                                                        */
66;/*  CALLED BY                                                             */
67;/*                                                                        */
68;/*    ISRs                                                                */
69;/*                                                                        */
70;/*  RELEASE HISTORY                                                       */
71;/*                                                                        */
72;/*    DATE              NAME                      DESCRIPTION             */
73;/*                                                                        */
74;/*  06-02-2021     William E. Lamie         Initial Version 6.1.7         */
75;/*  10-15-2021     William E. Lamie         Modified comment(s),          */
76;/*                                            resulting in version 6.1.9  */
77;/*  01-31-2022     William E. Lamie         Modified comment(s),          */
78;/*                                            resulting in version 6.1.10 */
79;/*  04-25-2022     William E. Lamie         Modified comment(s),          */
80;/*                                            resulting in version 6.1.11 */
81;/*                                                                        */
82;/**************************************************************************/
83;VOID   _tx_thread_context_save(VOID)
84;{
85    .global __tx_thread_context_save
86__tx_thread_context_save:
87;
88;    /* Upon entry to this routine, it is assumed that interrupts are locked
89;       out and the (interrupt) stack frame looks like the following:
90;
91;           (lower address) SP   ->     [return address of this call]
92;                           SP+4 ->     Saved R1
93;                           SP+8 ->     Saved R2
94;                           SP+12->     Interrupted PC
95;                           SP+16->     Interrupted PSW
96;
97;    /* Check for a nested interrupt condition.  */
98;    if (_tx_thread_system_state++)
99;    {
100;
101
102    MOV.L   #__tx_thread_system_state, R1       ; Pick up address of system state
103    MOV.L   [R1], R2                            ; Pick up system state
104    CMP     #0, R2                              ; 0 -> no nesting
105    BEQ     __tx_thread_not_nested_save
106;
107;    /* Nested interrupt condition.  */
108;
109    ADD   #1, r2                                ; _tx_thread_system_state++
110    MOV.L   r2, [r1]
111
112;
113;   /* Save the rest of the scratch registers on the interrupt stack and return to the
114;       calling ISR.  */
115    POP R1                                      ; recuperate return address from stack
116    PUSHM   R3-R5
117    PUSHM   R14-R15
118    PUSHC   FPSW                                ; (top) FPSW, R14, R15, R3, R4, R5, R1, R2, PC, PSW (bottom)
119    JMP     R1                                  ; Return address was preserved in R1
120
121;
122__tx_thread_not_nested_save:
123;    }
124;
125;    /* Otherwise, not nested, check to see if a thread was running.  */
126;    else if (_tx_thread_current_ptr)
127;    {
128;
129    ADD     #1, R2                              ; _tx_thread_system_state++
130    MOV.L   R2, [R1]
131
132    MOV.L   #__tx_thread_current_ptr, R2        ; Pickup current thread pointer
133    MOV.L   [R2], R2
134    CMP     #0,R2                               ; Is it NULL?
135    BEQ      __tx_thread_idle_system_save       ; Yes, idle system is running - idle restore
136;
137;    /* Move stack frame over to the current threads stack.  */
138;    /* complete stack frame with registers not saved yet (R3-R5, R14-R15, FPSW)   */
139;
140    MVFC    USP, R1                             ; Pick up user stack pointer
141    MOV.L   16[R0], R2
142    MOV.L   R2, [-R1]                           ; Save PSW on thread stack
143    MOV.L   12[R0], R2
144    MOV.L   R2, [-R1]                           ; Save PC on thread stack
145    MOV.L   8[R0], R2
146    MOV.L   R2, [-R1]                           ; Save R2 on thread stack
147    MOV.L   4[R0], R2
148    MOV.L   R2, [-R1]                           ; Save R1 on thread stack
149    MOV.L   R5, [-R1]                           ; Save R5 on thread stack
150    MOV.L   R4, [-R1]                           ; Save R4 on thread stack
151    MOV.L   R3, [-R1]                           ; Save R3 on thread stack
152    MOV.L   R15, [-R1]                          ; Save R15 on thread stack
153    MOV.L   R14, [-R1]                          ; Save R14 on thread stack
154    MVFC    FPSW, R3
155    MOV.L   R3, [-R1]                           ; Save FPSW on thread stack
156
157    POP     R2                                  ; Pick up return address from interrupt stack
158    ADD     #16, R0, R0                         ; Correct interrupt stack pointer back to the bottom
159    MVTC    R1, USP                             ; Set user/thread stack pointer
160    JMP     R2                                  ; Return to ISR
161
162;    }
163;    else
164;    {
165;
166__tx_thread_idle_system_save:
167;
168;        /* Interrupt occurred in the scheduling loop.  */
169;
170    POP     R1                                  ; Pick up return address
171    ADD     #16, R0, R0                         ; Correct interrupt stack pointer back to the bottom (PC), don't care about saved registers
172    JMP     R1                                  ; Return to caller
173;
174;    }
175;}
176    .end
177
178
179
180