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