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;
33FP          .set    A15
34DP          .set    B14
35SP          .set    B15
36;
37    .global     _tx_thread_system_state
38    .global     _tx_thread_current_ptr
39    .global     _tx_thread_system_stack_ptr
40;
41;
42    .sect   ".text"
43;/**************************************************************************/
44;/*                                                                        */
45;/*  FUNCTION                                               RELEASE        */
46;/*                                                                        */
47;/*    _tx_thread_context_save                             C667x/TI        */
48;/*                                                           6.1          */
49;/*  AUTHOR                                                                */
50;/*                                                                        */
51;/*    William E. Lamie, Microsoft Corporation                             */
52;/*                                                                        */
53;/*  DESCRIPTION                                                           */
54;/*                                                                        */
55;/*    This function saves the context of an executing thread in the       */
56;/*    beginning of interrupt processing.  The function also ensures that  */
57;/*    the system stack is used upon return to the calling ISR.            */
58;/*                                                                        */
59;/*  INPUT                                                                 */
60;/*                                                                        */
61;/*    None                                                                */
62;/*                                                                        */
63;/*  OUTPUT                                                                */
64;/*                                                                        */
65;/*    None                                                                */
66;/*                                                                        */
67;/*  CALLS                                                                 */
68;/*                                                                        */
69;/*    None                                                                */
70;/*                                                                        */
71;/*  CALLED BY                                                             */
72;/*                                                                        */
73;/*    ISRs                                                                */
74;/*                                                                        */
75;/*  RELEASE HISTORY                                                       */
76;/*                                                                        */
77;/*    DATE              NAME                      DESCRIPTION             */
78;/*                                                                        */
79;/*  09-30-2020     William E. Lamie         Initial Version 6.1           */
80;/*                                                                        */
81;/**************************************************************************/
82;VOID   _tx_thread_context_save(VOID)
83;{
84    .global _tx_thread_context_save
85_tx_thread_context_save:
86;
87;    /* Upon entry to this routine, it is assumed that all interrupts are locked
88;       out, an initial stack frame of 288 bytes has been allocated and registers
89;       A0, A1, A2, A3, A4, and B3 have been saved in the frame. Additionally,
90;       it is assumed that register B3 contains the ISR's return address.  */
91;
92;    /* Check for a nested interrupt condition.  */
93;    if (_tx_thread_system_state++)
94;    {
95;
96        MVKL        _tx_thread_system_state,A0          ; Build address of system state
97        MVKH        _tx_thread_system_state,A0          ;
98        LDW         *A0,A1                              ; Pickup current system state
99        STW         A5,*+SP(40)                         ; Save A5
100        STW         A6,*+SP(44)                         ; Save A6
101        STW         A7,*+SP(48)                         ; Save A7
102        STW         A8,*+SP(52)                         ; Save A8
103 [!A1]  B           _tx_thread_not_nested_save          ; If 0, not a nested save condition
104        MVKL        _tx_thread_current_ptr,A3           ; Build address of current thread ptr
105        MVKH        _tx_thread_current_ptr,A3           ;
106        LDW         *A3,A2                              ; Pickup current thread pointer
107        ADD         1,A1,A1                             ; Increment the system state (nested) counter
108        STW         A1,*A0                              ; Store system state
109;
110;    /* Nested interrupt condition. Save remaining scratch registers, and control registers
111;       and return to calling ISR.  */
112;
113        STW         A9,*+SP(56)                         ; Save A9
114        STW         B0,*+SP(84)                         ; Save B0
115        STW         B1,*+SP(88)                         ; Save B1
116        STW         B2,*+SP(92)                         ; Save B2
117                                                        ; B3 is already saved!
118        STW         B4,*+SP(100)                        ; Save B4
119        STW         B5,*+SP(104)                        ; Save B5
120        STW         B6,*+SP(108)                        ; Save B6
121        STW         B7,*+SP(112)                        ; Save B7
122        STW         B8,*+SP(116)                        ; Save B8
123        STW         B9,*+SP(120)                        ; Save B9
124        MVC         CSR,B0                              ; Pickup CSR
125        B           B3                                  ; Return to calling ISR
126        MVC         IRP,B1                              ; Pickup IRP
127        MVC         AMR,B2                              ; Pickup AMR
128        STW         B0,*+SP(8)                          ; Save CSR
129        STW         B1,*+SP(12)                         ; Save IRP
130        STW         B2,*+SP(16)                         ; Save AMR
131        ZERO        B0                                  ; Clear B0
132        MVC         B0,AMR                              ; Clear AMR for linear addressing in ISR
133        STW         A16,*+SP(140)                       ; Save A16
134        STW         A17,*+SP(144)                       ; Save A17
135        STW         A18,*+SP(148)                       ; Save A18
136        STW         A19,*+SP(152)                       ; Save A19
137        STW         A20,*+SP(156)                       ; Save A20
138        STW         A21,*+SP(160)                       ; Save A21
139        STW         A22,*+SP(164)                       ; Save A22
140        STW         A23,*+SP(168)                       ; Save A23
141        STW         A24,*+SP(172)                       ; Save A24
142        STW         A25,*+SP(176)                       ; Save A25
143        STW         A26,*+SP(180)                       ; Save A26
144        STW         A27,*+SP(184)                       ; Save A27
145        STW         A28,*+SP(188)                       ; Save A28
146        STW         A29,*+SP(192)                       ; Save A29
147        STW         A30,*+SP(196)                       ; Save A30
148        STW         A31,*+SP(200)                       ; Save A31
149        STW         B16,*+SP(204)                       ; Save B16
150        STW         B17,*+SP(208)                       ; Save B17
151        STW         B18,*+SP(212)                       ; Save B18
152        STW         B19,*+SP(216)                       ; Save B19
153        STW         B20,*+SP(220)                       ; Save B20
154        STW         B21,*+SP(224)                       ; Save B21
155        STW         B22,*+SP(228)                       ; Save B22
156        STW         B23,*+SP(232)                       ; Save B23
157        STW         B24,*+SP(236)                       ; Save B24
158        STW         B25,*+SP(240)                       ; Save B25
159        STW         B26,*+SP(244)                       ; Save B26
160        STW         B27,*+SP(248)                       ; Save B27
161        STW         B28,*+SP(252)                       ; Save B28
162        STW         B29,*+SP(256)                       ; Save B29
163        STW         B30,*+SP(260)                       ; Save B30
164        STW         B31,*+SP(264)                       ; Save B31
165        MVC         ILC,B0                              ; Pickup ILC
166        MVC         RILC,B1                             ; Pickup RILC
167        MVC         ITSR,B2                             ; Pickup ITSR
168        STW         B0,*+SP(268)                        ; Save ILC
169        STW         B1,*+SP(272)                        ; Save RILC
170        STW         B2,*+SP(276)                        ; Save ITSR
171;
172_tx_thread_not_nested_save:
173;    }
174;
175;    /* Otherwise, not nested, check to see if a thread was running.  */
176;    else if (_tx_thread_current_ptr)
177;    {
178;
179        MVKL        _tx_thread_system_stack_ptr,A0      ; Build address of system
180        MVKH        _tx_thread_system_stack_ptr,A0      ;   stack pointer
181        MV          A2,A1                               ; Transfer to A1 for B compare
182 [!A1]  B           _tx_thread_idle_system_save         ; If Null, idle system save
183        STW         A9,*+SP(56)                         ; Save A9
184        STW         B0,*+SP(84)                         ; Save B0
185        STW         B1,*+SP(88)                         ; Save B1
186        STW         B2,*+SP(92)                         ; Save B2
187        NOP                                             ; Delay slot
188;
189;    /* At this point, a thread was interrupted and the remainder of its scratch and
190;       control registers must be saved.  */
191;
192                                                        ; B3 was already saved!
193        STW         B4,*+SP(100)                        ; Save B4
194        STW         B5,*+SP(104)                        ; Save B5
195        STW         B6,*+SP(108)                        ; Save B6
196        STW         B7,*+SP(112)                        ; Save B7
197        STW         B8,*+SP(116)                        ; Save B8
198        STW         B9,*+SP(120)                        ; Save B9
199        MVC         CSR,B0                              ; Pickup CSR
200        MVC         IRP,B1                              ; Pickup IRP
201        MVC         AMR,B2                              ; Pickup AMR
202        STW         B0,*+SP(8)                          ; Save CSR
203        STW         B1,*+SP(12)                         ; Save IRP
204        STW         B2,*+SP(16)                         ; Save AMR
205        ZERO        B0                                  ; Clear B0
206        MVC         B0,AMR                              ; Clear AMR for linear addressing in ISR
207        STW         A16,*+SP(140)                       ; Save A16
208        STW         A17,*+SP(144)                       ; Save A17
209        STW         A18,*+SP(148)                       ; Save A18
210        STW         A19,*+SP(152)                       ; Save A19
211        STW         A20,*+SP(156)                       ; Save A20
212        STW         A21,*+SP(160)                       ; Save A21
213        STW         A22,*+SP(164)                       ; Save A22
214        STW         A23,*+SP(168)                       ; Save A23
215        STW         A24,*+SP(172)                       ; Save A24
216        STW         A25,*+SP(176)                       ; Save A25
217        STW         A26,*+SP(180)                       ; Save A26
218        STW         A27,*+SP(184)                       ; Save A27
219        STW         A28,*+SP(188)                       ; Save A28
220        STW         A29,*+SP(192)                       ; Save A29
221        STW         A30,*+SP(196)                       ; Save A30
222        STW         A31,*+SP(200)                       ; Save A31
223        STW         B16,*+SP(204)                       ; Save B16
224        STW         B17,*+SP(208)                       ; Save B17
225        STW         B18,*+SP(212)                       ; Save B18
226        STW         B19,*+SP(216)                       ; Save B19
227        STW         B20,*+SP(220)                       ; Save B20
228        STW         B21,*+SP(224)                       ; Save B21
229        STW         B22,*+SP(228)                       ; Save B22
230        STW         B23,*+SP(232)                       ; Save B23
231        STW         B24,*+SP(236)                       ; Save B24
232        STW         B25,*+SP(240)                       ; Save B25
233        STW         B26,*+SP(244)                       ; Save B26
234        STW         B27,*+SP(248)                       ; Save B27
235        STW         B28,*+SP(252)                       ; Save B28
236        STW         B29,*+SP(256)                       ; Save B29
237        STW         B30,*+SP(260)                       ; Save B30
238        STW         B31,*+SP(264)                       ; Save B31
239        MVC         ILC,B0                              ; Pickup ILC
240        MVC         RILC,B1                             ; Pickup RILC
241        MVC         ITSR,B2                             ; Pickup ITSR
242        STW         B0,*+SP(268)                        ; Save ILC
243        STW         B1,*+SP(272)                        ; Save RILC
244        STW         B2,*+SP(276)                        ; Save ITSR
245;
246;    /* Save the current stack pointer in the thread's control block.  */
247;    _tx_thread_current_ptr -> tx_thread_stack_ptr =  SP;
248;
249;    /* Switch to the system stack.  */
250;    SP =  _tx_thread_system_stack_ptr;
251;
252        STW         SP,*+A1(8)                          ; Save stack pointer
253        B           B3                                  ; Return to calling ISR
254        LDW         *A0,SP                              ; Switch to system stack
255        NOP         4                                   ; Stack pointer is valid upon return!
256;
257;    }
258;    else
259;    {
260;
261_tx_thread_idle_system_save:
262;
263;    /* Interrupt occurred in the scheduling loop.  */
264;
265;    /* Not much to do here, just adjust the stack pointer, and return to ISR
266;       processing.  */
267;
268        B           B3                                  ; Return to ISR
269        ADDK.S2     288,SP                              ; Recover stack space
270        NOP         4                                   ; Delay slot
271;
272;    }
273;}
274
275