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;/** ThreadX Component                                                     */
16;/**                                                                       */
17;/**   Thread                                                              */
18;/**                                                                       */
19;/**************************************************************************/
20;/**************************************************************************/
21#ifdef TX_INCLUDE_USER_DEFINE_FILE
22#include "tx_user.h"
23#endif
24
25    .equ    BTA, 0x412
26
27;/**************************************************************************/
28;/*                                                                        */
29;/*  FUNCTION                                               RELEASE        */
30;/*                                                                        */
31;/*    _tx_thread_schedule                               ARC_HS/MetaWare   */
32;/*                                                           6.2.1        */
33;/*  AUTHOR                                                                */
34;/*                                                                        */
35;/*    William E. Lamie, Microsoft Corporation                             */
36;/*                                                                        */
37;/*  DESCRIPTION                                                           */
38;/*                                                                        */
39;/*    This function waits for a thread control block pointer to appear in */
40;/*    the _tx_thread_execute_ptr variable.  Once a thread pointer appears */
41;/*    in the variable, the corresponding thread is resumed.               */
42;/*                                                                        */
43;/*  INPUT                                                                 */
44;/*                                                                        */
45;/*    None                                                                */
46;/*                                                                        */
47;/*  OUTPUT                                                                */
48;/*                                                                        */
49;/*    None                                                                */
50;/*                                                                        */
51;/*  CALLS                                                                 */
52;/*                                                                        */
53;/*    None                                                                */
54;/*                                                                        */
55;/*  CALLED BY                                                             */
56;/*                                                                        */
57;/*    _tx_initialize_kernel_enter          ThreadX entry function         */
58;/*    _tx_thread_system_return             Return to system from thread   */
59;/*    _tx_thread_context_restore           Restore thread's context       */
60;/*                                                                        */
61;/*  RELEASE HISTORY                                                       */
62;/*                                                                        */
63;/*    DATE              NAME                      DESCRIPTION             */
64;/*                                                                        */
65;/*  09-30-2020     William E. Lamie         Initial Version 6.1           */
66;/*  10-15-2021     Andres Mlinar            Modified comment(s),          */
67;/*                                            use schedule reenter,       */
68;/*                                            resulting in version 6.1.9  */
69;/*  03-08-2023     Cindy Deng               Modified comment(s), added    */
70;/*                                            #include tx_user.h,         */
71;/*                                            resulting in version 6.2.1  */
72;/*                                                                        */
73;/**************************************************************************/
74;VOID   _tx_thread_schedule(VOID)
75;{
76    .global _tx_thread_schedule
77    .type   _tx_thread_schedule, @function
78_tx_thread_schedule:
79
80    mov     r0, _estack
81    st      r0, [gp, _tx_thread_system_stack_ptr@sda]   ; Clean the system stack
82
83    .global _tx_thread_schedule_reenter
84    .type   _tx_thread_schedule_reenter, @function
85_tx_thread_schedule_reenter:
86
87
88;
89;    /* Switch to system stack.  */
90;
91    ld      sp, [gp, _tx_thread_system_stack_ptr@sda]   ; Switch to system stack
92;
93;    /* Enable interrupts.  */
94;
95    mov     r0, 0x1F                                    ; Build enable interrupt value
96    seti    r0                                          ; Enable interrupts
97;
98;    /* Wait for a thread to execute.  */
99;    do
100;    {
101;
102__tx_thread_schedule_loop:
103;
104    ld      r0, [gp, _tx_thread_execute_ptr@sda]        ; Pickup next thread to execute
105    breq    r0, 0, __tx_thread_schedule_loop            ; If NULL, keep looking
106;
107;    }
108;    while(_tx_thread_execute_ptr == TX_NULL);
109;
110;    /* Yes! We have a thread to execute.  Lockout interrupts and
111;       transfer control to it.  */
112;
113    clri                                                ; Lockout interrupts
114    nop                                                 ; Delay for interrupts to really be disabled
115;
116;    /* Setup the current thread pointer.  */
117;    _tx_thread_current_ptr =  _tx_thread_execute_ptr;
118;
119    st      r0, [gp, _tx_thread_current_ptr@sda]        ; Setup current thread pointer
120;
121;    /* Increment the run count for this thread.  */
122;    _tx_thread_current_ptr -> tx_thread_run_count++;
123;
124    ld      r3, [r0, 4]                                 ; Pickup run counter
125    ld      r4, [r0, 24]                                ; Pickup time-slice for this thread
126    add     r3, r3, 1                                   ; Increment run counter
127    st      r3, [r0, 4]                                 ; Store the new run counter
128;
129;    /* Setup time-slice, if present.  */
130;    _tx_timer_time_slice =  _tx_thread_current_ptr -> tx_thread_time_slice;
131;
132    st      r4, [gp, _tx_timer_time_slice@sda]          ; Setup time-slice
133;
134    .ifdef TX_ENABLE_EXECUTION_CHANGE_NOTIFY
135;
136;    /* Call the thread entry function to indicate the thread is executing.  */
137;
138    bl.d    _tx_execution_thread_enter                  ; Call the thread execution enter function
139    sub     sp, sp, 16                                  ; ..allocating some space on the stack
140    add     sp, sp, 16                                  ; Recover the stack space
141    .endif
142;
143;    /* Switch to the thread's stack.  */
144;    sp =  _tx_thread_execute_ptr -> tx_thread_stack_ptr;
145;
146    ld      sp, [r0, 8]                                 ; Switch to thread's stack
147    ld      r1, [sp, 0]                                 ; Pickup stack type
148    brlt    r1, 2, __tx_restore_non_hw_context          ; If less than 2, restore a software context
149    breq    r1, 3, __tx_hw_interrupt_restore            ; If interrupt restore, restore interrupted hardware context
150    ld      r2, [sp, 4]                                 ; Pickup status32
151    kflag   r2                                          ; Enter the proper register bank
152    ld      r3, [sp, 8]                                 ; Pickup the saved interrupt posture
153    add     sp, sp, 12                                  ; Recover small stack frame
154    j_s.d   [blink]                                     ; Return to thread and restore flags
155    seti    r3                                          ; Recover STATUS32
156
157__tx_hw_interrupt_restore:
158
159    mov     r0, 0x2                                     ; Pretend level 1 interrupt is returning
160    sr      r0, [AUX_IRQ_ACT]                           ;
161
162    .ifndef  TX_DISABLE_LP
163    ld      r0, [sp, 4]                                 ; Recover LP_START
164    sr      r0, [LP_START]                              ; Restore LP_START
165    ld      r1, [sp, 8]                                 ; Recover LP_END
166    sr      r1, [LP_END]                                ; Restore LP_END
167    ld      r2, [sp, 12]                                ; Recover LP_COUNT
168    mov     LP_COUNT, r2
169    .endif
170
171    .ifdef   TX_ENABLE_ACC
172    ld      r58, [sp, 140]                              ; Recover r58
173    ld      r59, [sp, 144]                              ; Recover r59
174    .endif
175
176    ld      r0, [sp, 156]                               ; Pickup saved BTA
177    sr      r0, [BTA]                                   ; Recover BTA
178    ld      ilink, [sp, 20]                             ; Recover ilink
179    ld      r0, [sp, 164]                               ; Pickup the interrupted status32
180    bclr    r0, r0, 31                                  ; Make sure interrupts are not enabled
181    kflag   r0                                          ; Switch to the proper register bank
182    add     sp, sp, 160                                 ; Recover the interrupt stack frame
183    rtie                                                ; Return to point of interrupt
184
185__tx_restore_non_hw_context:
186;
187;    /* Determine if an interrupt frame or a synchronous task suspension frame
188;       is present.  */
189;
190    ld      r1, [sp, 0]                                 ; Pickup the stack type
191    brne    r1, 0, __tx_thread_schedule_int_ret         ; Compare to solicited stack type. If not, thread was interrupted
192    ld      blink, [sp, 4]                              ; Recover blink
193    ld      fp,  [sp, 8]                                ; Recover fp
194    ld      gp,  [sp, 12]                               ; Recover gp
195    ld      r25, [sp, 16]                               ; Recover r25
196    ld      r24, [sp, 20]                               ; Recover r24
197    ld      r23, [sp, 24]                               ; Recover r23
198    ld      r22, [sp, 28]                               ; Recover r22
199    ld      r21, [sp, 32]                               ; Recover r21
200    ld      r20, [sp, 36]                               ; Recover r20
201    ld      r19, [sp, 40]                               ; Recover r19
202    ld      r18, [sp, 44]                               ; Recover r18
203    ld      r17, [sp, 48]                               ; Recover r17
204    ld      r16, [sp, 52]                               ; Recover r16
205    ld      r15, [sp, 56]                               ; Recover r15
206    ld      r14, [sp, 60]                               ; Recover r14
207    ld      r13, [sp, 64]                               ; Recover r13
208    ld      r1,  [sp, 68]                               ; Pickup STATUS32
209    ld      r30, [sp, 72]                               ; Recover r30
210    add     sp, sp, 76                                  ; Recover solicited stack frame
211    j_s.d   [blink]                                     ; Return to thread and restore flags
212    seti    r1                                          ; Recover STATUS32
213;
214__tx_thread_schedule_int_ret:
215;
216    mov     r0, 0x2                                     ; Pretend level 1 interrupt is returning
217    sr      r0, [AUX_IRQ_ACT]                           ;
218
219    .ifndef  TX_DISABLE_LP
220    ld      r0, [sp, 4]                                 ; Recover LP_START
221    sr      r0, [LP_START]                              ; Restore LP_START
222    ld      r1, [sp, 8]                                 ; Recover LP_END
223    sr      r1, [LP_END]                                ; Restore LP_END
224    ld      r2, [sp, 12]                                ; Recover LP_COUNT
225    mov     LP_COUNT, r2
226    .endif
227
228    ld      r0, [sp, 156]                               ; Pickup saved BTA
229    sr      r0, [BTA]                                   ; Recover BTA
230    ld      blink, [sp, 16]                             ; Recover blink
231    ld      ilink, [sp, 20]                             ; Recover ilink
232    ld      fp, [sp, 24]                                ; Recover fp
233    ld      gp, [sp, 28]                                ; Recover gp
234    ld      r25, [sp, 32]                               ; Recover r25
235    ld      r24, [sp, 36]                               ; Recover r24
236    ld      r23, [sp, 40]                               ; Recover r23
237    ld      r22, [sp, 44]                               ; Recover r22
238    ld      r21, [sp, 48]                               ; Recover r21
239    ld      r20, [sp, 52]                               ; Recover r20
240    ld      r19, [sp, 56]                               ; Recover r19
241    ld      r18, [sp, 60]                               ; Recover r18
242    ld      r17, [sp, 64]                               ; Recover r17
243    ld      r16, [sp, 68]                               ; Recover r16
244    ld      r15, [sp, 72]                               ; Recover r15
245    ld      r14, [sp, 76]                               ; Recover r14
246    ld      r13, [sp, 80]                               ; Recover r13
247    ld      r12, [sp, 84]                               ; Recover r12
248    ld      r11, [sp, 88]                               ; Recover r11
249    ld      r10, [sp, 92]                               ; Recover r10
250    ld      r9,  [sp, 96]                               ; Recover r9
251    ld      r8,  [sp, 100]                              ; Recover r8
252    ld      r7,  [sp, 104]                              ; Recover r7
253    ld      r6,  [sp, 108]                              ; Recover r6
254    ld      r5,  [sp, 112]                              ; Recover r5
255    ld      r4,  [sp, 116]                              ; Recover r4
256    ld      r3,  [sp, 120]                              ; Recover r3
257    ld      r2,  [sp, 124]                              ; Recover r2
258    ld      r1,  [sp, 128]                              ; Recover r1
259    ld      r0,  [sp, 132]                              ; Recover r0
260    ld      r30, [sp, 136]                              ; Recover r30
261    .ifdef   TX_ENABLE_ACC
262    ld      r58, [sp, 140]                              ; Recover r58
263    ld      r59, [sp, 144]                              ; Recover r59
264    .endif
265    add     sp, sp, 160                                 ; Recover interrupt stack frame
266    rtie                                                ; Return to point of interrupt
267;
268;}
269;
270    .end
271
272