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/** */ 16/** ThreadX Component */ 17/** */ 18/** Thread */ 19/** */ 20/**************************************************************************/ 21/**************************************************************************/ 22 23 24/* #define TX_SOURCE_CODE */ 25 26 27/* Include necessary system files. */ 28 29/* #include "tx_api.h" 30 #include "tx_thread.h" 31 #include "tx_timer.h" */ 32 33 34 EXTERN _tx_thread_execute_ptr 35 EXTERN _tx_thread_current_ptr 36 EXTERN _tx_timer_time_slice 37#ifdef TX_ENABLE_EXECUTION_CHANGE_NOTIFY 38 EXTERN _tx_execution_thread_enter 39#endif 40 41 42 SECTION `.text`:CODE:REORDER:NOROOT(2) 43 CODE 44/**************************************************************************/ 45/* */ 46/* FUNCTION RELEASE */ 47/* */ 48/* _tx_thread_schedule RISC-V32/IAR */ 49/* 6.1 */ 50/* AUTHOR */ 51/* */ 52/* William E. Lamie, Microsoft Corporation */ 53/* Tom van Leeuwen, Technolution B.V. */ 54/* */ 55/* DESCRIPTION */ 56/* */ 57/* This function waits for a thread control block pointer to appear in */ 58/* the _tx_thread_execute_ptr variable. Once a thread pointer appears */ 59/* in the variable, the corresponding thread is resumed. */ 60/* */ 61/* INPUT */ 62/* */ 63/* None */ 64/* */ 65/* OUTPUT */ 66/* */ 67/* None */ 68/* */ 69/* CALLS */ 70/* */ 71/* None */ 72/* */ 73/* CALLED BY */ 74/* */ 75/* _tx_initialize_kernel_enter ThreadX entry function */ 76/* _tx_thread_system_return Return to system from thread */ 77/* _tx_thread_context_restore Restore thread's context */ 78/* */ 79/* RELEASE HISTORY */ 80/* */ 81/* DATE NAME DESCRIPTION */ 82/* */ 83/* 09-30-2020 William E. Lamie Initial Version 6.1 */ 84/* */ 85/**************************************************************************/ 86/* VOID _tx_thread_schedule(VOID) 87{ */ 88 PUBLIC _tx_thread_schedule 89_tx_thread_schedule: 90 91 /* Enable interrupts. */ 92 csrsi mstatus, 0x08 ; Enable interrupts 93 94 /* Wait for a thread to execute. */ 95 /* do 96 { */ 97 98 la t0, _tx_thread_execute_ptr ; Pickup address of execute ptr 99_tx_thread_schedule_loop: 100 lw t1, 0(t0) ; Pickup next thread to execute 101 beqz t1, _tx_thread_schedule_loop ; If NULL, wait for thread to execute 102 103 /* } 104 while(_tx_thread_execute_ptr == TX_NULL); */ 105 106 /* Yes! We have a thread to execute. Lockout interrupts and 107 transfer control to it. */ 108 csrci mstatus, 0x08 ; Lockout interrupts 109 110 /* Setup the current thread pointer. */ 111 /* _tx_thread_current_ptr = _tx_thread_execute_ptr; */ 112 113 la t0, _tx_thread_current_ptr ; Pickup current thread pointer address 114 sw t1, 0(t0) ; Set current thread pointer 115 116 /* Increment the run count for this thread. */ 117 /* _tx_thread_current_ptr -> tx_thread_run_count++; */ 118 119 lw t2, 4(t1) ; Pickup run count 120 lw t3, 24(t1) ; Pickup time slice value 121 addi t2, t2, 1 ; Increment run count 122 sw t2, 4(t1) ; Store new run count 123 124 /* Setup time-slice, if present. */ 125 /* _tx_timer_time_slice = _tx_thread_current_ptr -> tx_thread_time_slice; */ 126 127 la t2, _tx_timer_time_slice ; Pickup time-slice variable address 128 129 /* Switch to the thread's stack. */ 130 /* SP = _tx_thread_execute_ptr -> tx_thread_stack_ptr; */ 131 132 lw sp, 8(t1) ; Switch to thread's stack 133 sw t3, 0(t2) ; Store new time-slice*/ 134 135#ifdef TX_ENABLE_EXECUTION_CHANGE_NOTIFY 136 137 call _tx_execution_thread_enter ; Call the thread execution enter function 138#endif 139 140 /* Determine if an interrupt frame or a synchronous task suspension frame 141 is present. */ 142 143 lw t2, 0(sp) ; Pickup stack type 144 beqz t2, _tx_thread_synch_return ; If 0, solicited thread return 145 146 /* Determine if floating point registers need to be recovered. */ 147 148#if __iar_riscv_base_isa == rv32e 149 flw f0, 0x7C(sp) ; Recover ft0 150 flw f1, 0x80(sp) ; Recover ft1 151 flw f2, 0x84(sp) ; Recover ft2 152 flw f3, 0x88(sp) ; Recover ft3 153 flw f4, 0x8C(sp) ; Recover ft4 154 flw f5, 0x90(sp) ; Recover ft5 155 flw f6, 0x94(sp) ; Recover ft6 156 flw f7, 0x98(sp) ; Recover ft7 157 flw f8, 0x9C(sp) ; Recover fs0 158 flw f9, 0xA0(sp) ; Recover fs1 159 flw f10,0xA4(sp) ; Recover fa0 160 flw f11,0xA8(sp) ; Recover fa1 161 flw f12,0xAC(sp) ; Recover fa2 162 flw f13,0xB0(sp) ; Recover fa3 163 flw f14,0xB4(sp) ; Recover fa4 164 flw f15,0xB8(sp) ; Recover fa5 165 flw f16,0xBC(sp) ; Recover fa6 166 flw f17,0xC0(sp) ; Recover fa7 167 flw f18,0xC4(sp) ; Recover fs2 168 flw f19,0xC8(sp) ; Recover fs3 169 flw f20,0xCC(sp) ; Recover fs4 170 flw f21,0xD0(sp) ; Recover fs5 171 flw f22,0xD4(sp) ; Recover fs6 172 flw f23,0xD8(sp) ; Recover fs7 173 flw f24,0xDC(sp) ; Recover fs8 174 flw f25,0xE0(sp) ; Recover fs9 175 flw f26,0xE4(sp) ; Recover fs10 176 flw f27,0xE8(sp) ; Recover fs11 177 flw f28,0xEC(sp) ; Recover ft8 178 flw f29,0xF0(sp) ; Recover ft9 179 flw f30,0xF4(sp) ; Recover ft10 180 flw f31,0xF8(sp) ; Recover ft11 181 lw t0, 0xFC(sp) ; Recover fcsr 182 csrw fcsr, t0 ; 183#endif 184 185 /* Recover standard registers. */ 186 187 lw t0, 0x78(sp) ; Recover mepc 188 csrw mepc, t0 ; Store mepc 189 li t0, 0x1880 ; Prepare MPIP 190 csrw mstatus, t0 ; Enable MPIP 191 192 lw x1, 0x70(sp) ; Recover RA 193 lw x5, 0x4C(sp) ; Recover t0 194 lw x6, 0x48(sp) ; Recover t1 195 lw x7, 0x44(sp) ; Recover t2 196 lw x8, 0x30(sp) ; Recover s0 197 lw x9, 0x2C(sp) ; Recover s1 198 lw x10, 0x6C(sp) ; Recover a0 199 lw x11, 0x68(sp) ; Recover a1 200 lw x12, 0x64(sp) ; Recover a2 201 lw x13, 0x60(sp) ; Recover a3 202 lw x14, 0x5C(sp) ; Recover a4 203 lw x15, 0x58(sp) ; Recover a5 204 lw x16, 0x54(sp) ; Recover a6 205 lw x17, 0x50(sp) ; Recover a7 206 lw x18, 0x28(sp) ; Recover s2 207 lw x19, 0x24(sp) ; Recover s3 208 lw x20, 0x20(sp) ; Recover s4 209 lw x21, 0x1C(sp) ; Recover s5 210 lw x22, 0x18(sp) ; Recover s6 211 lw x23, 0x14(sp) ; Recover s7 212 lw x24, 0x10(sp) ; Recover s8 213 lw x25, 0x0C(sp) ; Recover s9 214 lw x26, 0x08(sp) ; Recover s10 215 lw x27, 0x04(sp) ; Recover s11 216 lw x28, 0x40(sp) ; Recover t3 217 lw x29, 0x3C(sp) ; Recover t4 218 lw x30, 0x38(sp) ; Recover t5 219 lw x31, 0x34(sp) ; Recover t6 220 221#if __iar_riscv_base_isa == rv32e 222 addi sp, sp, 260 ; Recover stack frame - with floating point registers 223#else 224 addi sp, sp, 128 ; Recover stack frame - without floating point registers 225#endif 226 mret ; Return to point of interrupt 227 228_tx_thread_synch_return: 229 230#if __iar_riscv_base_isa == rv32e 231 flw f8, 0x3C(sp) ; Recover fs0 232 flw f9, 0x40(sp) ; Recover fs1 233 flw f18,0x44(sp) ; Recover fs2 234 flw f19,0x48(sp) ; Recover fs3 235 flw f20,0x4C(sp) ; Recover fs4 236 flw f21,0x50(sp) ; Recover fs5 237 flw f22,0x54(sp) ; Recover fs6 238 flw f23,0x58(sp) ; Recover fs7 239 flw f24,0x5C(sp) ; Recover fs8 240 flw f25,0x60(sp) ; Recover fs9 241 flw f26,0x64(sp) ; Recover fs10 242 flw f27,0x68(sp) ; Recover fs11 243 lw t0, 0x6C(sp) ; Recover fcsr 244 csrw fcsr, t0 ; 245#endif 246 247 /* Recover standard preserved registers. */ 248 /* Recover standard registers. */ 249 250 lw x1, 0x34(sp) ; Recover RA 251 lw x8, 0x30(sp) ; Recover s0 252 lw x9, 0x2C(sp) ; Recover s1 253 lw x18, 0x28(sp) ; Recover s2 254 lw x19, 0x24(sp) ; Recover s3 255 lw x20, 0x20(sp) ; Recover s4 256 lw x21, 0x1C(sp) ; Recover s5 257 lw x22, 0x18(sp) ; Recover s6 258 lw x23, 0x14(sp) ; Recover s7 259 lw x24, 0x10(sp) ; Recover s8 260 lw x25, 0x0C(sp) ; Recover s9 261 lw x26, 0x08(sp) ; Recover s10 262 lw x27, 0x04(sp) ; Recover s11 263 lw t0, 0x38(sp) ; Recover mstatus 264 csrw mstatus, t0 ; Store mstatus, enables interrupt 265#if __iar_riscv_base_isa == rv32e 266 addi sp, sp, 116 ; Recover stack frame 267#else 268 addi sp, sp, 64 ; Recover stack frame 269#endif 270 ret ; Return to thread 271 272/* } */ 273 END 274 275