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