mirror of
https://github.com/espressif/esp-idf.git
synced 2024-10-05 20:47:46 -04:00
c36dd7834f
RISC-V stack pointer should always be 16 byte aligned, but for some cases where we were doing manual SP manipulation this was not always the case.
111 lines
3.0 KiB
ArmAsm
111 lines
3.0 KiB
ArmAsm
// Copyright 2015-2020 Espressif Systems (Shanghai) PTE LTD
|
|
//
|
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
|
// you may not use this file except in compliance with the License.
|
|
// You may obtain a copy of the License at
|
|
|
|
// http://www.apache.org/licenses/LICENSE-2.0
|
|
//
|
|
// Unless required by applicable law or agreed to in writing, software
|
|
// distributed under the License is distributed on an "AS IS" BASIS,
|
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
// See the License for the specific language governing permissions and
|
|
// limitations under the License.
|
|
|
|
.global uxInterruptNesting
|
|
.global uxSchedulerRunning
|
|
.global xIsrStackTop
|
|
.global pxCurrentTCB
|
|
.global vTaskSwitchContext
|
|
.global xPortSwitchFlag
|
|
|
|
.section .text
|
|
|
|
/**
|
|
* This function makes the RTOS aware about a ISR entering, it takes the
|
|
* current task stack saved, places into the TCB, loads the ISR stack
|
|
* the interrupted stack must be passed in a0. It needs to receive the
|
|
* ISR nesting code improvements
|
|
*/
|
|
|
|
.global rtos_int_enter
|
|
.type rtos_int_enter, @function
|
|
rtos_int_enter:
|
|
/* preserve the return address */
|
|
mv t1, ra
|
|
mv t2, a0
|
|
|
|
/* scheduler not enabled, jump directly to ISR handler */
|
|
lw t0, uxSchedulerRunning
|
|
beq t0,zero, rtos_enter_end
|
|
|
|
/* increments the ISR nesting count */
|
|
la t3, uxInterruptNesting
|
|
lw t4, 0x0(t3)
|
|
addi t5,t4,1
|
|
sw t5, 0x0(t3)
|
|
|
|
/* If reached here from another low-prio ISR, skip stack pushing to TCB */
|
|
bne t4,zero, rtos_enter_end
|
|
|
|
/* Save current TCB and load the ISR stack */
|
|
lw t0, pxCurrentTCB
|
|
sw t2, 0x0(t0)
|
|
lw sp, xIsrStackTop
|
|
|
|
rtos_enter_end:
|
|
mv ra, t1
|
|
ret
|
|
|
|
/**
|
|
* Recovers the next task to run stack pointer and place it into
|
|
* a0, then the interrupt handler can restore the context of
|
|
* the next task
|
|
*/
|
|
.global rtos_int_exit
|
|
.type rtos_int_exit, @function
|
|
rtos_int_exit:
|
|
/* may skip RTOS aware interrupt since scheduler was not started */
|
|
lw t0, uxSchedulerRunning
|
|
beq t0,zero, rtos_exit_end
|
|
|
|
/* update nesting interrupts counter */
|
|
la t2, uxInterruptNesting
|
|
lw t3, 0x0(t2)
|
|
|
|
/* Already zero, protect against underflow */
|
|
beq t3, zero, isr_skip_decrement
|
|
addi t3,t3, -1
|
|
sw t3, 0x0(t2)
|
|
|
|
isr_skip_decrement:
|
|
|
|
/* may still have interrupts pending, skip section below and exit */
|
|
bne t3,zero,rtos_exit_end
|
|
|
|
/* Schedule the next task if a yield is pending */
|
|
la t0, xPortSwitchFlag
|
|
lw t2, 0x0(t0)
|
|
beq t2, zero, no_switch
|
|
|
|
/* preserve return address and schedule next task
|
|
stack pointer for riscv should always be 16 byte aligned */
|
|
addi sp,sp,-16
|
|
sw ra, 0(sp)
|
|
call vTaskSwitchContext
|
|
lw ra, 0(sp)
|
|
addi sp, sp, 16
|
|
|
|
/* Clears the switch pending flag */
|
|
la t0, xPortSwitchFlag
|
|
mv t2, zero
|
|
sw t2, 0x0(t0)
|
|
|
|
no_switch:
|
|
/* Recover the stack of next task and prepare to exit : */
|
|
lw a0, pxCurrentTCB
|
|
lw a0, 0x0(a0)
|
|
|
|
rtos_exit_end:
|
|
ret
|