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