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;
32#ifdef TX_ENABLE_FIQ_SUPPORT
33ENABLE_INTS     DEFINE  0xC0                    ; IRQ & FIQ Interrupts enabled mask
34#else
35ENABLE_INTS     DEFINE  0x80                    ; IRQ Interrupts enabled mask
36#endif
37;
38;
39    EXTERN     _tx_thread_execute_ptr
40    EXTERN     _tx_thread_current_ptr
41    EXTERN     _tx_timer_time_slice
42    EXTERN     _tx_execution_thread_enter
43;
44;
45;
46;/**************************************************************************/
47;/*                                                                        */
48;/*  FUNCTION                                               RELEASE        */
49;/*                                                                        */
50;/*    _tx_thread_schedule                                  ARM9/IAR       */
51;/*                                                           6.1          */
52;/*  AUTHOR                                                                */
53;/*                                                                        */
54;/*    William E. Lamie, Microsoft Corporation                             */
55;/*                                                                        */
56;/*  DESCRIPTION                                                           */
57;/*                                                                        */
58;/*    This function waits for a thread control block pointer to appear in */
59;/*    the _tx_thread_execute_ptr variable.  Once a thread pointer appears */
60;/*    in the variable, the corresponding thread is resumed.               */
61;/*                                                                        */
62;/*  INPUT                                                                 */
63;/*                                                                        */
64;/*    None                                                                */
65;/*                                                                        */
66;/*  OUTPUT                                                                */
67;/*                                                                        */
68;/*    None                                                                */
69;/*                                                                        */
70;/*  CALLS                                                                 */
71;/*                                                                        */
72;/*    None                                                                */
73;/*                                                                        */
74;/*  CALLED BY                                                             */
75;/*                                                                        */
76;/*    _tx_initialize_kernel_enter          ThreadX entry function         */
77;/*    _tx_thread_system_return             Return to system from thread   */
78;/*    _tx_thread_context_restore           Restore thread's context       */
79;/*                                                                        */
80;/*  RELEASE HISTORY                                                       */
81;/*                                                                        */
82;/*    DATE              NAME                      DESCRIPTION             */
83;/*                                                                        */
84;/*  09-30-2020     William E. Lamie         Initial Version 6.1           */
85;/*                                                                        */
86;/**************************************************************************/
87;VOID   _tx_thread_schedule(VOID)
88;{
89    RSEG    .text:CODE:NOROOT(2)
90    PUBLIC  _tx_thread_schedule
91    CODE32
92_tx_thread_schedule??rA
93_tx_thread_schedule
94;
95;    /* Enable interrupts.  */
96;
97    MRS     r2, CPSR                            ; Pickup CPSR
98    BIC     r0, r2, #ENABLE_INTS                ; Clear the disable bit(s)
99    MSR     CPSR_cxsf, r0                       ; Enable interrupts
100;
101;    /* Wait for a thread to execute.  */
102;    do
103;    {
104    LDR     r1, =_tx_thread_execute_ptr         ; Address of thread execute ptr
105;
106__tx_thread_schedule_loop
107;
108    LDR     r0, [r1, #0]                        ; Pickup next thread to execute
109    CMP     r0, #0                              ; Is it NULL?
110    BEQ     __tx_thread_schedule_loop           ; If so, keep looking for a thread
111;
112;    }
113;    while(_tx_thread_execute_ptr == TX_NULL);
114;
115;    /* Yes! We have a thread to execute.  Lockout interrupts and
116;       transfer control to it.  */
117;
118    MSR     CPSR_cxsf, r2                       ; Disable interrupts
119;
120;    /* Setup the current thread pointer.  */
121;    _tx_thread_current_ptr =  _tx_thread_execute_ptr;
122;
123    LDR     r1, =_tx_thread_current_ptr         ; Pickup address of current thread
124    STR     r0, [r1, #0]                        ; Setup current thread pointer
125;
126;    /* Increment the run count for this thread.  */
127;    _tx_thread_current_ptr -> tx_thread_run_count++;
128;
129    LDR     r2, [r0, #4]                        ; Pickup run counter
130    LDR     r3, [r0, #24]                       ; Pickup time-slice for this thread
131    ADD     r2, r2, #1                          ; Increment thread run-counter
132    STR     r2, [r0, #4]                        ; Store the new run counter
133;
134;    /* Setup time-slice, if present.  */
135;    _tx_timer_time_slice =  _tx_thread_current_ptr -> tx_thread_time_slice;
136;
137    LDR     r2, =_tx_timer_time_slice           ; Pickup address of time slice
138                                                ;   variable
139    LDR     sp, [r0, #8]                        ; Switch stack pointers
140    STR     r3, [r2, #0]                        ; Setup time-slice
141;
142;    /* Switch to the thread's stack.  */
143;    sp =  _tx_thread_execute_ptr -> tx_thread_stack_ptr;
144;
145#ifdef TX_ENABLE_EXECUTION_CHANGE_NOTIFY
146;
147;    /* Call the thread entry function to indicate the thread is executing.  */
148;
149    BL      _tx_execution_thread_enter          ; Call the thread execution enter function
150#endif
151;
152;    /* Determine if an interrupt frame or a synchronous task suspension frame
153;   is present.  */
154;
155    LDMIA   sp!, {r0, r1}                       ; Pickup the stack type and saved CPSR
156    CMP     r0, #0                              ; Check for synchronous context switch
157    MSRNE   SPSR_cxsf, r1                       ;   Setup SPSR for return
158    LDMNEIA sp!, {r0-r12, lr, pc}^              ; Return to point of thread interrupt
159    LDMIA   sp!, {r4-r11, lr}                   ; Return to thread synchronously
160    MSR     CPSR_cxsf, r1                       ;   Recover CPSR
161#ifdef TX_THUMB
162    BX      lr                                  ; Return to caller
163#else
164    MOV     pc, lr                              ; Return to caller
165#endif
166;
167;}
168;
169    END
170
171