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