1;/***************************************************************************
2; * Copyright (c) 2024 Microsoft Corporation
3; *
4; * This program and the accompanying materials are made available under the
5; * terms of the MIT License which is available at
6; * https://opensource.org/licenses/MIT.
7; *
8; * SPDX-License-Identifier: MIT
9; **************************************************************************/
10;
11;
12;/**************************************************************************/
13;/**************************************************************************/
14;/**                                                                       */
15;/** ThreadX Component                                                     */
16;/**                                                                       */
17;/**   Thread                                                              */
18;/**                                                                       */
19;/**************************************************************************/
20;/**************************************************************************/
21;
22;
23;#define TX_SOURCE_CODE
24;
25;
26;/* Include necessary system files.  */
27;
28;#include "tx_api.h"
29;#include "tx_thread.h"
30;#include "tx_timer.h"
31;
32FP          .set    A15
33DP          .set    B14
34SP          .set    B15
35;
36    .global     _tx_thread_system_state
37    .global     _tx_thread_current_ptr
38    .global     _tx_thread_system_stack_ptr
39    .global     _tx_thread_execute_ptr
40    .global     _tx_timer_time_slice
41    .global     _tx_thread_schedule
42    .global     _tx_thread_preempt_disable
43;
44;
45    .sect   ".text"
46;/**************************************************************************/
47;/*                                                                        */
48;/*  FUNCTION                                               RELEASE        */
49;/*                                                                        */
50;/*    _tx_thread_context_restore                          C667x/TI        */
51;/*                                                           6.1          */
52;/*  AUTHOR                                                                */
53;/*                                                                        */
54;/*    William E. Lamie, Microsoft Corporation                             */
55;/*                                                                        */
56;/*  DESCRIPTION                                                           */
57;/*                                                                        */
58;/*    This function restores the interrupt context if it is processing a  */
59;/*    nested interrupt.  If not, it returns to the interrupt thread if no */
60;/*    preemption is necessary.  Otherwise, if preemption is necessary or  */
61;/*    if no thread was running, the function returns to the scheduler.    */
62;/*                                                                        */
63;/*  INPUT                                                                 */
64;/*                                                                        */
65;/*    None                                                                */
66;/*                                                                        */
67;/*  OUTPUT                                                                */
68;/*                                                                        */
69;/*    None                                                                */
70;/*                                                                        */
71;/*  CALLS                                                                 */
72;/*                                                                        */
73;/*    _tx_thread_schedule                   Thread scheduling routine     */
74;/*                                                                        */
75;/*  CALLED BY                                                             */
76;/*                                                                        */
77;/*    ISRs                                  Interrupt Service Routines    */
78;/*                                                                        */
79;/*  RELEASE HISTORY                                                       */
80;/*                                                                        */
81;/*    DATE              NAME                      DESCRIPTION             */
82;/*                                                                        */
83;/*  09-30-2020     William E. Lamie         Initial Version 6.1           */
84;/*                                                                        */
85;/**************************************************************************/
86;VOID   _tx_thread_context_restore(VOID)
87;{
88    .global _tx_thread_context_restore
89_tx_thread_context_restore:
90;
91;    /* Lockout interrupts.  */
92;
93        MVC         CSR,B0                              ; Pickup CSR
94        AND         -2,B0,B0                            ; Build interrupt lockout value
95        MVC         B0,CSR                              ; Lockout interrupts
96;
97;    /* Determine if interrupts are nested.  */
98;    if (--_tx_thread_system_state)
99;    {
100;
101        MVKL        _tx_thread_system_state,A0          ; Build address of system state
102        MVKH        _tx_thread_system_state,A0          ;
103        LDW         *A0,A1                              ; Pickup system state variable
104        MVKL        _tx_thread_current_ptr,A2           ; Build address of current thread ptr
105        NOP         3                                   ; Delay slots
106        SUB         A1,1,A1                             ; Decrement system state
107 [!A1]  B           _tx_thread_not_nested_restore       ; If 0, not a nested restore
108        MVKH        _tx_thread_current_ptr,A2           ;
109        LDW         *A2,A3                              ; Pickup current thread pointer
110        STW         A1,*A0                              ; Store system state
111        NOP         2                                   ; Delay slots
112;
113;    /* Interrupts are nested.  */
114;
115;    /* Just recover the saved registers and return to the point of
116;       interrupt.  */
117;
118        LDW         *+SP(8),B0                          ; Recover saved CSR
119        LDW         *+SP(12),B1                         ; Recover saved IRP
120        LDW         *+SP(16),B2                         ; Recover saved AMR
121        LDW         *+SP(20),A0                         ; Recover A0
122        LDW         *+SP(24),A1                         ; Recover A1
123        LDW         *+SP(28),A2                         ; Recover A2
124        LDW         *+SP(32),A3                         ; Recover A3
125        LDW         *+SP(36),A4                         ; Recover A4
126        LDW         *+SP(40),A5                         ; Recover A5
127        LDW         *+SP(44),A6                         ; Recover A6
128        LDW         *+SP(48),A7                         ; Recover A7
129        LDW         *+SP(52),A8                         ; Recover A8
130        LDW         *+SP(56),A9                         ; Recover A9
131        MVC         B0,CSR                              ; Setup CSR
132        MVC         B1,IRP                              ; Setup IRP
133        MVC         B2,AMR                              ; Setup AMR
134        LDW         *+SP(268),B0                        ; Recover saved ILC
135        LDW         *+SP(272),B1                        ; Recover saved RILC
136        LDW         *+SP(276),B2                        ; Recover saved ITSR
137        NOP         4
138        MVC         B0,ILC                              ; Setup ILC
139        MVC         B1,RILC                             ; Setup RILC
140        MVC         B2,ITSR                             ; Setup ITSR
141        LDW         *+SP(84),B0                         ; Recover B0
142        LDW         *+SP(88),B1                         ; Recover B1
143        LDW         *+SP(92),B2                         ; Recover B2
144        LDW         *+SP(100),B4                        ; Recover B4
145        LDW         *+SP(104),B5                        ; Recover B5
146        LDW         *+SP(108),B6                        ; Recover B6
147        LDW         *+SP(112),B7                        ; Recover B7
148        LDW         *+SP(116),B8                        ; Recover B8
149        LDW         *+SP(140),A16                       ; Recover A16
150        LDW         *+SP(144),A17                       ; Recover A17
151        LDW         *+SP(148),A18                       ; Recover A18
152        LDW         *+SP(152),A19                       ; Recover A19
153        LDW         *+SP(156),A20                       ; Recover A20
154        LDW         *+SP(160),A21                       ; Recover A21
155        LDW         *+SP(164),A22                       ; Recover A22
156        LDW         *+SP(168),A23                       ; Recover A23
157        LDW         *+SP(172),A24                       ; Recover A24
158        LDW         *+SP(176),A25                       ; Recover A25
159        LDW         *+SP(180),A26                       ; Recover A26
160        LDW         *+SP(184),A27                       ; Recover A27
161        LDW         *+SP(188),A28                       ; Recover A28
162        LDW         *+SP(192),A29                       ; Recover A29
163        LDW         *+SP(196),A30                       ; Recover A30
164        LDW         *+SP(200),A31                       ; Recover A31
165        LDW         *+SP(204),B16                       ; Recover B16
166        LDW         *+SP(208),B17                       ; Recover B17
167        LDW         *+SP(212),B18                       ; Recover B18
168        LDW         *+SP(216),B19                       ; Recover B19
169        LDW         *+SP(220),B20                       ; Recover B20
170        LDW         *+SP(224),B21                       ; Recover B21
171        LDW         *+SP(228),B22                       ; Recover B22
172        LDW         *+SP(232),B23                       ; Recover B23
173        LDW         *+SP(236),B24                       ; Recover B24
174        LDW         *+SP(240),B25                       ; Recover B25
175        LDW         *+SP(244),B26                       ; Recover B26
176        LDW         *+SP(248),B27                       ; Recover B27
177        LDW         *+SP(252),B28                       ; Recover B28
178        LDW         *+SP(256),B29                       ; Recover B29
179        LDW         *+SP(260),B30                       ; Recover B30
180        LDW         *+SP(264),B31                       ; Recover B31
181        B           IRP                                 ; Return to point of interrupt
182||      LDW         *+SP(120),B9                        ; Recover B9
183        LDW         *+SP(96),B3                         ; Recover B3
184        ADDK.S2     288,SP                              ; Recover stack space
185        NOP         3                                   ; Delay slots
186;
187;    }
188_tx_thread_not_nested_restore:
189;
190;    /* Determine if a thread was interrupted and no preemption is required.  */
191;    else if (((_tx_thread_current_ptr) && (_tx_thread_current_ptr == _tx_thread_execute_ptr))
192;               || (_tx_thread_preempt_disable))
193;    {
194;
195        NOP                                             ; Delay
196        MV          A3,A1                               ; Move thread pointer into A1
197 [!A1]  B           _tx_thread_schedule                 ; If null, idle system restore
198        MVKL        _tx_thread_preempt_disable,A0       ; Build preempt disable flag address
199        MVKH        _tx_thread_preempt_disable,A0       ;
200        MVKL        _tx_thread_execute_ptr,A4           ; Build execute thread pointer
201        MVKH        _tx_thread_execute_ptr,A4           ;
202        LDW         *A0,B1                              ; Pickup preempt disable flag
203
204        LDW         *A4,A6                              ; Pickup next thread to execute
205        NOP         4                                   ; Delay slot
206        CMPEQ       A6,A1,A7                            ; Determine if threads are the same?
207        ADD         A7,B1,B1                            ; Add results together
208 [B1]   B           _tx_thread_no_preempt_restore       ; If set, skip preeemption
209        LDW         *+A1(8),A6                          ; Recover thread's stack pointer
210        MVKL        _tx_timer_time_slice,A5             ; Build time slice address
211        MVKH        _tx_timer_time_slice,A5             ;
212        LDW         *A5,B1                              ; Pickup current time-slice
213        NOP                                             ; Delay slot
214;
215;
216_tx_thread_preempt_restore:
217;
218;
219        MVKL        1,A0                                ; Build the interrupt stack type
220        STW         A0,*+A6(4)                          ; Save stack type
221;
222;   /* Store the remaining registers on the thread's stack.  */
223;
224        STW         A10,*+A6(60)                        ; Save A10
225        STW         A11,*+A6(64)                        ; Save A11
226        STW         A12,*+A6(68)                        ; Save A12
227        STW         A13,*+A6(72)                        ; Save A13
228        STW         A14,*+A6(76)                        ; Save A14
229        STW         A15,*+A6(80)                        ; Save A15 (FP)
230        STW         B10,*+A6(124)                       ; Save B10
231        ADDK        128,A6                              ; Move stack pointer
232        STW         B11,*+A6(0)                         ; Save B11
233        STW         B12,*+A6(4)                         ; Save B12
234        STW         B13,*+A6(8)                         ; Save B13
235;
236;    /* Save the remaining time-slice and disable it.  */
237;    if (_tx_timer_time_slice)
238;    {
239;
240;        _tx_thread_current_ptr -> tx_thread_time_slice =  _tx_timer_time_slice;
241;        _tx_timer_time_slice =  0;
242;
243;    }
244_tx_thread_dont_save_ts:
245;
246;
247;    /* Clear the current task pointer.  */
248;    _tx_thread_current_ptr =  TX_NULL;
249;
250;    /* Return to the scheduler.  */
251;    _tx_thread_schedule();
252;
253        B           _tx_thread_schedule                 ; Return to scheduler
254        STW         B1,*+A1(24)                         ; Store current time-slice
255        ZERO        A3                                  ; Clear value
256        STW         A3,*A2                              ; Set current thread pointer to NULL
257        STW         A3,*A5                              ; Set time slice to 0
258        NOP                                             ; Delay
259;
260;
261_tx_thread_no_preempt_restore:
262;
263;    /* Restore interrupted thread.  */
264;
265;    /* Pickup the saved stack pointer.  */
266;    SP =  _tx_thread_current_ptr -> tx_thread_stack_ptr;
267;
268;   /* Recover the saved context and return to the point of interrupt.  */
269;
270        MV          A6,SP                               ; Setup real stack pointer
271        LDW         *+SP(8),B0                          ; Recover saved CSR
272        LDW         *+SP(12),B1                         ; Recover saved IRP
273        LDW         *+SP(16),B2                         ; Recover saved AMR
274        LDW         *+SP(20),A0                         ; Recover A0
275        LDW         *+SP(24),A1                         ; Recover A1
276        LDW         *+SP(28),A2                         ; Recover A2
277        LDW         *+SP(32),A3                         ; Recover A3
278        LDW         *+SP(36),A4                         ; Recover A4
279        LDW         *+SP(40),A5                         ; Recover A5
280        LDW         *+SP(44),A6                         ; Recover A6
281        LDW         *+SP(48),A7                         ; Recover A7
282        LDW         *+SP(52),A8                         ; Recover A8
283        LDW         *+SP(56),A9                         ; Recover A9
284        MVC         B0,CSR                              ; Setup CSR
285        MVC         B1,IRP                              ; Setup IRP
286        MVC         B2,AMR                              ; Setup AMR
287        LDW         *+SP(268),B0                        ; Recover saved ILC
288        LDW         *+SP(272),B1                        ; Recover saved RILC
289        LDW         *+SP(276),B2                        ; Recover saved ITSR
290        NOP         4                                   ; Delay
291        MVC         B0,ILC                              ; Setup ILC
292        MVC         B1,RILC                             ; Setup RILC
293        MVC         B2,ITSR                             ; Setup ITSR
294        LDW         *+SP(84),B0                         ; Recover B0
295        LDW         *+SP(88),B1                         ; Recover B1
296        LDW         *+SP(92),B2                         ; Recover B2
297        LDW         *+SP(100),B4                        ; Recover B4
298        LDW         *+SP(104),B5                        ; Recover B5
299        LDW         *+SP(108),B6                        ; Recover B6
300        LDW         *+SP(112),B7                        ; Recover B7
301        LDW         *+SP(116),B8                        ; Recover B8
302        LDW         *+SP(140),A16                       ; Recover A16
303        LDW         *+SP(144),A17                       ; Recover A17
304        LDW         *+SP(148),A18                       ; Recover A18
305        LDW         *+SP(152),A19                       ; Recover A19
306        LDW         *+SP(156),A20                       ; Recover A20
307        LDW         *+SP(160),A21                       ; Recover A21
308        LDW         *+SP(164),A22                       ; Recover A22
309        LDW         *+SP(168),A23                       ; Recover A23
310        LDW         *+SP(172),A24                       ; Recover A24
311        LDW         *+SP(176),A25                       ; Recover A25
312        LDW         *+SP(180),A26                       ; Recover A26
313        LDW         *+SP(184),A27                       ; Recover A27
314        LDW         *+SP(188),A28                       ; Recover A28
315        LDW         *+SP(192),A29                       ; Recover A29
316        LDW         *+SP(196),A30                       ; Recover A30
317        LDW         *+SP(200),A31                       ; Recover A31
318        LDW         *+SP(204),B16                       ; Recover B16
319        LDW         *+SP(208),B17                       ; Recover B17
320        LDW         *+SP(212),B18                       ; Recover B18
321        LDW         *+SP(216),B19                       ; Recover B19
322        LDW         *+SP(220),B20                       ; Recover B20
323        LDW         *+SP(224),B21                       ; Recover B21
324        LDW         *+SP(228),B22                       ; Recover B22
325        LDW         *+SP(232),B23                       ; Recover B23
326        LDW         *+SP(236),B24                       ; Recover B24
327        LDW         *+SP(240),B25                       ; Recover B25
328        LDW         *+SP(244),B26                       ; Recover B26
329        LDW         *+SP(248),B27                       ; Recover B27
330        LDW         *+SP(252),B28                       ; Recover B28
331        LDW         *+SP(256),B29                       ; Recover B29
332        LDW         *+SP(260),B30                       ; Recover B30
333        LDW         *+SP(264),B31                       ; Recover B31
334        B           IRP                                 ; Return to point of interrupt
335||      LDW         *+SP(120),B9                        ; Recover B9
336        LDW         *+SP(96),B3                         ; Recover B3
337        ADDK.S2     288,SP                              ; Recover stack space
338        NOP         3                                   ; Delay slots
339;
340;    }
341;}
342
343