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