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