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 EXTERN _tx_thread_current_ptr 34 EXTERN _tx_thread_system_state 35 EXTERN _tx_thread_system_stack_ptr 36#ifdef TX_ENABLE_EXECUTION_CHANGE_NOTIFY 37 EXTERN _tx_execution_isr_enter 38#endif 39 40 41 SECTION `.text`:CODE:REORDER:NOROOT(2) 42 CODE 43/**************************************************************************/ 44/* */ 45/* FUNCTION RELEASE */ 46/* */ 47/* _tx_thread_context_save 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 saves the context of an executing thread in the */ 57/* beginning of interrupt processing. The function also ensures that */ 58/* the system stack is used upon return to the calling ISR. */ 59/* */ 60/* INPUT */ 61/* */ 62/* None */ 63/* */ 64/* OUTPUT */ 65/* */ 66/* None */ 67/* */ 68/* CALLS */ 69/* */ 70/* None */ 71/* */ 72/* CALLED BY */ 73/* */ 74/* ISRs */ 75/* */ 76/* RELEASE HISTORY */ 77/* */ 78/* DATE NAME DESCRIPTION */ 79/* */ 80/* 09-30-2020 William E. Lamie Initial Version 6.1 */ 81/* */ 82/**************************************************************************/ 83/* VOID _tx_thread_context_save(VOID) 84{ */ 85 PUBLIC _tx_thread_context_save 86_tx_thread_context_save: 87 88 /* Upon entry to this routine, it is assumed that interrupts are locked 89 out and the interrupt stack fame has been allocated and x1 (ra) has 90 been saved on the stack. */ 91 92 sw x5, 0x4C(sp) ; First store t0 and t1 93 sw x6, 0x48(sp) 94 95 la x5, _tx_thread_system_state ; Pickup address of system state 96 lw x6, 0(x5) ; Pickup system state 97 98 /* Check for a nested interrupt condition. */ 99 /* if (_tx_thread_system_state++) 100 { */ 101 beqz x6, _tx_thread_not_nested_save ; If 0, first interrupt condition 102 addi x6, x6, 1 ; Increment the interrupt counter 103 sw x6, 0(x5) ; Store the interrupt counter 104 105 /* Nested interrupt condition. 106 Save the reset of the scratch registers on the stack and return to the 107 calling ISR. */ 108 109 sw x7, 0x44(sp) ; Store t2 110 sw x8, 0x30(sp) ; Store s0 111 sw x10, 0x6C(sp) ; Store a0 112 sw x11, 0x68(sp) ; Store a1 113 sw x12, 0x64(sp) ; Store a2 114 sw x13, 0x60(sp) ; Store a3 115 sw x14, 0x5C(sp) ; Store a4 116 sw x15, 0x58(sp) ; Store a5 117 sw x16, 0x54(sp) ; Store a6 118 sw x17, 0x50(sp) ; Store a7 119 sw x28, 0x40(sp) ; Store t3 120 sw x29, 0x3C(sp) ; Store t4 121 sw x30, 0x38(sp) ; Store t5 122 sw x31, 0x34(sp) ; Store t6 123 csrr t0, mepc ; Load exception program counter 124 sw t0, 0x78(sp) ; Save it on the stack 125 126#if __iar_riscv_base_isa == rv32e 127 128 /* Save floating point scratch registers. */ 129 130 fsw f0, 0x7C(sp) ; Store ft0 131 fsw f1, 0x80(sp) ; Store ft1 132 fsw f2, 0x84(sp) ; Store ft2 133 fsw f3, 0x88(sp) ; Store ft3 134 fsw f4, 0x8C(sp) ; Store ft4 135 fsw f5, 0x90(sp) ; Store ft5 136 fsw f6, 0x94(sp) ; Store ft6 137 fsw f7, 0x98(sp) ; Store ft7 138 fsw f10,0xA4(sp) ; Store fa0 139 fsw f11,0xA8(sp) ; Store fa1 140 fsw f12,0xAC(sp) ; Store fa2 141 fsw f13,0xB0(sp) ; Store fa3 142 fsw f14,0xB4(sp) ; Store fa4 143 fsw f15,0xB8(sp) ; Store fa5 144 fsw f16,0xBC(sp) ; Store fa6 145 fsw f17,0xC0(sp) ; Store fa7 146 fsw f28,0xEC(sp) ; Store ft8 147 fsw f29,0xF0(sp) ; Store ft9 148 fsw f30,0xF4(sp) ; Store ft10 149 fsw f31,0xF8(sp) ; Store ft11 150 csrr t0, fcsr 151 sw t0, 0xFC(sp) ; Store fcsr 152#endif 153 154#ifdef TX_ENABLE_EXECUTION_CHANGE_NOTIFY 155 call _tx_execution_isr_enter ; Call the ISR execution enter function 156#endif 157 158 ret ; Return to calling ISR 159 160_tx_thread_not_nested_save: 161 /* } */ 162 163 /* Otherwise, not nested, check to see if a thread was running. */ 164 /* else if (_tx_thread_current_ptr) 165 { */ 166 addi x6, x6, 1 ; Increment the interrupt counter 167 sw x6, 0(x5) ; Store the interrupt counter 168 169 /* Not nested: Find the user thread that was running and load our SP */ 170 171 lw x5, _tx_thread_current_ptr ; Pickup current thread pointer 172 beqz x5, _tx_thread_idle_system_save ; If NULL, idle system was interrupted 173 174 /* Save the standard scratch registers. */ 175 176 sw x7, 0x44(sp) ; Store t2 177 sw x8, 0x30(sp) ; Store s0 178 sw x10, 0x6C(sp) ; Store a0 179 sw x11, 0x68(sp) ; Store a1 180 sw x12, 0x64(sp) ; Store a2 181 sw x13, 0x60(sp) ; Store a3 182 sw x14, 0x5C(sp) ; Store a4 183 sw x15, 0x58(sp) ; Store a5 184 sw x16, 0x54(sp) ; Store a6 185 sw x17, 0x50(sp) ; Store a7 186 sw x28, 0x40(sp) ; Store t3 187 sw x29, 0x3C(sp) ; Store t4 188 sw x30, 0x38(sp) ; Store t5 189 sw x31, 0x34(sp) ; Store t6 190 191 csrr t0, mepc ; Load exception program counter 192 sw t0, 0x78(sp) ; Save it on the stack 193 194#if __iar_riscv_base_isa == rv32e 195 196 /* Save floating point scratch registers. */ 197 198 fsw f0, 0x7C(sp) ; Store ft0 199 fsw f1, 0x80(sp) ; Store ft1 200 fsw f2, 0x84(sp) ; Store ft2 201 fsw f3, 0x88(sp) ; Store ft3 202 fsw f4, 0x8C(sp) ; Store ft4 203 fsw f5, 0x90(sp) ; Store ft5 204 fsw f6, 0x94(sp) ; Store ft6 205 fsw f7, 0x98(sp) ; Store ft7 206 fsw f10,0xA4(sp) ; Store fa0 207 fsw f11,0xA8(sp) ; Store fa1 208 fsw f12,0xAC(sp) ; Store fa2 209 fsw f13,0xB0(sp) ; Store fa3 210 fsw f14,0xB4(sp) ; Store fa4 211 fsw f15,0xB8(sp) ; Store fa5 212 fsw f16,0xBC(sp) ; Store fa6 213 fsw f17,0xC0(sp) ; Store fa7 214 fsw f28,0xEC(sp) ; Store ft8 215 fsw f29,0xF0(sp) ; Store ft9 216 fsw f30,0xF4(sp) ; Store ft10 217 fsw f31,0xF8(sp) ; Store ft11 218 csrr t0, fcsr 219 sw t0, 0xFC(sp) ; Store fcsr 220#endif 221 222 /* Save the current stack pointer in the thread's control block. */ 223 /* _tx_thread_current_ptr -> tx_thread_stack_ptr = sp; */ 224 225 /* Switch to the system stack. */ 226 /* sp = _tx_thread_system_stack_ptr; */ 227 228 lw t1, _tx_thread_current_ptr ; Pickup current thread pointer 229 sw sp, 8(t1) ; Save stack pointer*/ 230 231#ifdef TX_ENABLE_EXECUTION_CHANGE_NOTIFY 232 /* _tx_execution_isr_enter is called with thread stack pointer */ 233 call _tx_execution_isr_enter ; Call the ISR execution enter function 234#endif 235 236 237 lw sp, _tx_thread_system_stack_ptr ; Switch to system stack 238 ret ; Return to calling ISR 239 240 /* } 241 else 242 { */ 243 244_tx_thread_idle_system_save: 245 246 247#ifdef TX_ENABLE_EXECUTION_CHANGE_NOTIFY 248 call _tx_execution_isr_enter ; Call the ISR execution enter function 249#endif 250 251 /* Interrupt occurred in the scheduling loop. */ 252 253 /* } 254} */ 255#if __iar_riscv_base_isa == rv32e 256 addi sp, sp, 260 ; Recover stack frame - with floating point enabled 257#else 258 addi sp, sp, 128 ; Recover the reserved stack space 259#endif 260 ret ; Return to calling ISR 261 262 END 263