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