1// Copyright 2015-2020 Espressif Systems (Shanghai) PTE LTD 2// 3// Licensed under the Apache License, Version 2.0 (the "License"); 4// you may not use this file except in compliance with the License. 5// You may obtain a copy of the License at 6 7// http://www.apache.org/licenses/LICENSE-2.0 8// 9// Unless required by applicable law or agreed to in writing, software 10// distributed under the License is distributed on an "AS IS" BASIS, 11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12// See the License for the specific language governing permissions and 13// limitations under the License. 14 15 .global uxInterruptNesting 16 .global uxSchedulerRunning 17 .global xIsrStackTop 18 .global pxCurrentTCB 19 .global vTaskSwitchContext 20 .global xPortSwitchFlag 21 22 .section .text 23 24/** 25 * This function makes the RTOS aware about a ISR entering, it takes the 26 * current task stack saved, places into the TCB, loads the ISR stack 27 * the interrupted stack must be passed in a0. It needs to receive the 28 * ISR nesting code improvements 29 */ 30 31 .global rtos_int_enter 32 .type rtos_int_enter, @function 33rtos_int_enter: 34 /* preserve the return address */ 35 mv t1, ra 36 mv t2, a0 37 38 /* scheduler not enabled, jump directly to ISR handler */ 39 lw t0, uxSchedulerRunning 40 beq t0,zero, rtos_enter_end 41 42 /* increments the ISR nesting count */ 43 la t3, uxInterruptNesting 44 lw t4, 0x0(t3) 45 addi t5,t4,1 46 sw t5, 0x0(t3) 47 48 /* If reached here from another low-prio ISR, skip stack pushing to TCB */ 49 bne t4,zero, rtos_enter_end 50 51 /* Save current TCB and load the ISR stack */ 52 lw t0, pxCurrentTCB 53 sw t2, 0x0(t0) 54 lw sp, xIsrStackTop 55 56rtos_enter_end: 57 mv ra, t1 58 ret 59 60/** 61 * Recovers the next task to run stack pointer and place it into 62 * a0, then the interrupt handler can restore the context of 63 * the next task 64 */ 65 .global rtos_int_exit 66 .type rtos_int_exit, @function 67rtos_int_exit: 68 /* may skip RTOS aware interrupt since scheduler was not started */ 69 lw t0, uxSchedulerRunning 70 beq t0,zero, rtos_exit_end 71 72 /* update nesting interrupts counter */ 73 la t2, uxInterruptNesting 74 lw t3, 0x0(t2) 75 76 /* Already zero, protect against underflow */ 77 beq t3, zero, isr_skip_decrement 78 addi t3,t3, -1 79 sw t3, 0x0(t2) 80 81isr_skip_decrement: 82 83 /* may still have interrupts pending, skip section below and exit */ 84 bne t3,zero,rtos_exit_end 85 86 /* Schedule the next task if a yield is pending */ 87 la t0, xPortSwitchFlag 88 lw t2, 0x0(t0) 89 beq t2, zero, no_switch 90 91 /* preserve return address and schedule next task 92 stack pointer for riscv should always be 16 byte aligned */ 93 addi sp,sp,-16 94 sw ra, 0(sp) 95 call vTaskSwitchContext 96 lw ra, 0(sp) 97 addi sp, sp, 16 98 99 /* Clears the switch pending flag */ 100 la t0, xPortSwitchFlag 101 mv t2, zero 102 sw t2, 0x0(t0) 103 104no_switch: 105 /* Recover the stack of next task and prepare to exit : */ 106 lw a0, pxCurrentTCB 107 lw a0, 0x0(a0) 108 109rtos_exit_end: 110 ret 111