|
|
|
@ -69,11 +69,6 @@
|
|
|
|
|
|
|
|
|
|
#include "freertos_risc_v_chip_specific_extensions.h"
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
#ifndef portasmHANDLE_INTERRUPT
|
|
|
|
|
#error portasmHANDLE_INTERRUPT must be defined to the function to be called to handle external/peripheral interrupts. portasmHANDLE_INTERRUPT can be defined on the assembler command line or in the appropriate freertos_risc_v_chip_specific_extensions.h header file. https://www.freertos.org/Using-FreeRTOS-on-RISC-V.html
|
|
|
|
|
#endif
|
|
|
|
|
*/
|
|
|
|
|
#ifndef portasmHAS_SIFIVE_CLINT
|
|
|
|
|
#define portasmHAS_SIFIVE_CLINT 0
|
|
|
|
|
#endif
|
|
|
|
@ -85,6 +80,8 @@ specific version of freertos_risc_v_chip_specific_extensions.h. See the notes
|
|
|
|
|
at the top of this file. */
|
|
|
|
|
#define portCONTEXT_SIZE ( 30 * portWORD_SIZE )
|
|
|
|
|
|
|
|
|
|
.global timer_irq_handler
|
|
|
|
|
.global ecall_handler
|
|
|
|
|
.global xPortStartFirstTask
|
|
|
|
|
.global freertos_risc_v_trap_handler
|
|
|
|
|
.global pxPortInitialiseStack
|
|
|
|
@ -99,7 +96,6 @@ at the top of this file. */
|
|
|
|
|
.extern xISRStackTop
|
|
|
|
|
#.extern portasmHANDLE_INTERRUPT
|
|
|
|
|
.extern xPortClearTimerIntPending
|
|
|
|
|
|
|
|
|
|
/*-----------------------------------------------------------*/
|
|
|
|
|
|
|
|
|
|
.align 8
|
|
|
|
@ -287,6 +283,177 @@ processed_source:
|
|
|
|
|
.endfunc
|
|
|
|
|
/*-----------------------------------------------------------*/
|
|
|
|
|
|
|
|
|
|
.align 3
|
|
|
|
|
.func
|
|
|
|
|
timer_irq_handler:
|
|
|
|
|
|
|
|
|
|
addi sp, sp, -portCONTEXT_SIZE
|
|
|
|
|
store_x x1, 1 * portWORD_SIZE( sp )
|
|
|
|
|
store_x x5, 2 * portWORD_SIZE( sp )
|
|
|
|
|
store_x x6, 3 * portWORD_SIZE( sp )
|
|
|
|
|
store_x x7, 4 * portWORD_SIZE( sp )
|
|
|
|
|
store_x x8, 5 * portWORD_SIZE( sp )
|
|
|
|
|
store_x x9, 6 * portWORD_SIZE( sp )
|
|
|
|
|
store_x x10, 7 * portWORD_SIZE( sp )
|
|
|
|
|
store_x x11, 8 * portWORD_SIZE( sp )
|
|
|
|
|
store_x x12, 9 * portWORD_SIZE( sp )
|
|
|
|
|
store_x x13, 10 * portWORD_SIZE( sp )
|
|
|
|
|
store_x x14, 11 * portWORD_SIZE( sp )
|
|
|
|
|
store_x x15, 12 * portWORD_SIZE( sp )
|
|
|
|
|
store_x x16, 13 * portWORD_SIZE( sp )
|
|
|
|
|
store_x x17, 14 * portWORD_SIZE( sp )
|
|
|
|
|
store_x x18, 15 * portWORD_SIZE( sp )
|
|
|
|
|
store_x x19, 16 * portWORD_SIZE( sp )
|
|
|
|
|
store_x x20, 17 * portWORD_SIZE( sp )
|
|
|
|
|
store_x x21, 18 * portWORD_SIZE( sp )
|
|
|
|
|
store_x x22, 19 * portWORD_SIZE( sp )
|
|
|
|
|
store_x x23, 20 * portWORD_SIZE( sp )
|
|
|
|
|
store_x x24, 21 * portWORD_SIZE( sp )
|
|
|
|
|
store_x x25, 22 * portWORD_SIZE( sp )
|
|
|
|
|
store_x x26, 23 * portWORD_SIZE( sp )
|
|
|
|
|
store_x x27, 24 * portWORD_SIZE( sp )
|
|
|
|
|
store_x x28, 25 * portWORD_SIZE( sp )
|
|
|
|
|
store_x x29, 26 * portWORD_SIZE( sp )
|
|
|
|
|
store_x x30, 27 * portWORD_SIZE( sp )
|
|
|
|
|
store_x x31, 28 * portWORD_SIZE( sp )
|
|
|
|
|
|
|
|
|
|
load_x t0, pxCurrentTCB /* Load pxCurrentTCB. */
|
|
|
|
|
store_x sp, 0( t0 ) /* Write sp to first TCB member. */
|
|
|
|
|
|
|
|
|
|
csrr a1, mepc
|
|
|
|
|
store_x a1, 0( sp ) /* Asynch so save unmodified exception return address. */
|
|
|
|
|
|
|
|
|
|
load_x sp, xISRStackTop /* Switch to ISR stack before function call. */
|
|
|
|
|
call xPortClearTimerIntPending
|
|
|
|
|
jal xTaskIncrementTick
|
|
|
|
|
beqz a0, not_switch /* Don't switch context if incrementing tick didn't unblock a task. */
|
|
|
|
|
jal vTaskSwitchContext
|
|
|
|
|
|
|
|
|
|
not_switch:
|
|
|
|
|
load_x t1, pxCurrentTCB /* Load pxCurrentTCB. */
|
|
|
|
|
load_x sp, 0( t1 ) /* Read sp from first TCB member. */
|
|
|
|
|
|
|
|
|
|
/* Load mret with the address of the next instruction in the task to run next. */
|
|
|
|
|
load_x t0, 0( sp )
|
|
|
|
|
csrw mepc, t0
|
|
|
|
|
|
|
|
|
|
load_x x1, 1 * portWORD_SIZE( sp )
|
|
|
|
|
load_x x5, 2 * portWORD_SIZE( sp ) /* t0 */
|
|
|
|
|
load_x x6, 3 * portWORD_SIZE( sp ) /* t1 */
|
|
|
|
|
load_x x7, 4 * portWORD_SIZE( sp ) /* t2 */
|
|
|
|
|
load_x x8, 5 * portWORD_SIZE( sp ) /* s0/fp */
|
|
|
|
|
load_x x9, 6 * portWORD_SIZE( sp ) /* s1 */
|
|
|
|
|
load_x x10, 7 * portWORD_SIZE( sp ) /* a0 */
|
|
|
|
|
load_x x11, 8 * portWORD_SIZE( sp ) /* a1 */
|
|
|
|
|
load_x x12, 9 * portWORD_SIZE( sp ) /* a2 */
|
|
|
|
|
load_x x13, 10 * portWORD_SIZE( sp ) /* a3 */
|
|
|
|
|
load_x x14, 11 * portWORD_SIZE( sp ) /* a4 */
|
|
|
|
|
load_x x15, 12 * portWORD_SIZE( sp ) /* a5 */
|
|
|
|
|
load_x x16, 13 * portWORD_SIZE( sp ) /* a6 */
|
|
|
|
|
load_x x17, 14 * portWORD_SIZE( sp ) /* a7 */
|
|
|
|
|
load_x x18, 15 * portWORD_SIZE( sp ) /* s2 */
|
|
|
|
|
load_x x19, 16 * portWORD_SIZE( sp ) /* s3 */
|
|
|
|
|
load_x x20, 17 * portWORD_SIZE( sp ) /* s4 */
|
|
|
|
|
load_x x21, 18 * portWORD_SIZE( sp ) /* s5 */
|
|
|
|
|
load_x x22, 19 * portWORD_SIZE( sp ) /* s6 */
|
|
|
|
|
load_x x23, 20 * portWORD_SIZE( sp ) /* s7 */
|
|
|
|
|
load_x x24, 21 * portWORD_SIZE( sp ) /* s8 */
|
|
|
|
|
load_x x25, 22 * portWORD_SIZE( sp ) /* s9 */
|
|
|
|
|
load_x x26, 23 * portWORD_SIZE( sp ) /* s10 */
|
|
|
|
|
load_x x27, 24 * portWORD_SIZE( sp ) /* s11 */
|
|
|
|
|
load_x x28, 25 * portWORD_SIZE( sp ) /* t3 */
|
|
|
|
|
load_x x29, 26 * portWORD_SIZE( sp ) /* t4 */
|
|
|
|
|
load_x x30, 27 * portWORD_SIZE( sp ) /* t5 */
|
|
|
|
|
load_x x31, 28 * portWORD_SIZE( sp ) /* t6 */
|
|
|
|
|
addi sp, sp, portCONTEXT_SIZE
|
|
|
|
|
|
|
|
|
|
mret
|
|
|
|
|
.endfunc
|
|
|
|
|
|
|
|
|
|
.align 3
|
|
|
|
|
.func
|
|
|
|
|
ecall_handler:
|
|
|
|
|
|
|
|
|
|
addi sp, sp, -portCONTEXT_SIZE
|
|
|
|
|
store_x x1, 1 * portWORD_SIZE( sp )
|
|
|
|
|
store_x x5, 2 * portWORD_SIZE( sp )
|
|
|
|
|
store_x x6, 3 * portWORD_SIZE( sp )
|
|
|
|
|
store_x x7, 4 * portWORD_SIZE( sp )
|
|
|
|
|
store_x x8, 5 * portWORD_SIZE( sp )
|
|
|
|
|
store_x x9, 6 * portWORD_SIZE( sp )
|
|
|
|
|
store_x x10, 7 * portWORD_SIZE( sp )
|
|
|
|
|
store_x x11, 8 * portWORD_SIZE( sp )
|
|
|
|
|
store_x x12, 9 * portWORD_SIZE( sp )
|
|
|
|
|
store_x x13, 10 * portWORD_SIZE( sp )
|
|
|
|
|
store_x x14, 11 * portWORD_SIZE( sp )
|
|
|
|
|
store_x x15, 12 * portWORD_SIZE( sp )
|
|
|
|
|
store_x x16, 13 * portWORD_SIZE( sp )
|
|
|
|
|
store_x x17, 14 * portWORD_SIZE( sp )
|
|
|
|
|
store_x x18, 15 * portWORD_SIZE( sp )
|
|
|
|
|
store_x x19, 16 * portWORD_SIZE( sp )
|
|
|
|
|
store_x x20, 17 * portWORD_SIZE( sp )
|
|
|
|
|
store_x x21, 18 * portWORD_SIZE( sp )
|
|
|
|
|
store_x x22, 19 * portWORD_SIZE( sp )
|
|
|
|
|
store_x x23, 20 * portWORD_SIZE( sp )
|
|
|
|
|
store_x x24, 21 * portWORD_SIZE( sp )
|
|
|
|
|
store_x x25, 22 * portWORD_SIZE( sp )
|
|
|
|
|
store_x x26, 23 * portWORD_SIZE( sp )
|
|
|
|
|
store_x x27, 24 * portWORD_SIZE( sp )
|
|
|
|
|
store_x x28, 25 * portWORD_SIZE( sp )
|
|
|
|
|
store_x x29, 26 * portWORD_SIZE( sp )
|
|
|
|
|
store_x x30, 27 * portWORD_SIZE( sp )
|
|
|
|
|
store_x x31, 28 * portWORD_SIZE( sp )
|
|
|
|
|
|
|
|
|
|
load_x t0, pxCurrentTCB /* Load pxCurrentTCB. */
|
|
|
|
|
store_x sp, 0( t0 ) /* Write sp to first TCB member. */
|
|
|
|
|
|
|
|
|
|
csrr a1, mepc
|
|
|
|
|
addi a1, a1, 4 /* Synchronous so updated exception return address to the instruction after the instruction that generated the exeption. */
|
|
|
|
|
store_x a1, 0( sp ) /* Save updated exception return address. */
|
|
|
|
|
|
|
|
|
|
load_x sp, xISRStackTop /* Switch to ISR stack before function call. */
|
|
|
|
|
jal vTaskSwitchContext
|
|
|
|
|
|
|
|
|
|
load_x t1, pxCurrentTCB /* Load pxCurrentTCB. */
|
|
|
|
|
load_x sp, 0( t1 ) /* Read sp from first TCB member. */
|
|
|
|
|
|
|
|
|
|
/* Load mret with the address of the next instruction in the task to run next. */
|
|
|
|
|
load_x t0, 0( sp )
|
|
|
|
|
csrw mepc, t0
|
|
|
|
|
|
|
|
|
|
load_x x1, 1 * portWORD_SIZE( sp )
|
|
|
|
|
load_x x5, 2 * portWORD_SIZE( sp ) /* t0 */
|
|
|
|
|
load_x x6, 3 * portWORD_SIZE( sp ) /* t1 */
|
|
|
|
|
load_x x7, 4 * portWORD_SIZE( sp ) /* t2 */
|
|
|
|
|
load_x x8, 5 * portWORD_SIZE( sp ) /* s0/fp */
|
|
|
|
|
load_x x9, 6 * portWORD_SIZE( sp ) /* s1 */
|
|
|
|
|
load_x x10, 7 * portWORD_SIZE( sp ) /* a0 */
|
|
|
|
|
load_x x11, 8 * portWORD_SIZE( sp ) /* a1 */
|
|
|
|
|
load_x x12, 9 * portWORD_SIZE( sp ) /* a2 */
|
|
|
|
|
load_x x13, 10 * portWORD_SIZE( sp ) /* a3 */
|
|
|
|
|
load_x x14, 11 * portWORD_SIZE( sp ) /* a4 */
|
|
|
|
|
load_x x15, 12 * portWORD_SIZE( sp ) /* a5 */
|
|
|
|
|
load_x x16, 13 * portWORD_SIZE( sp ) /* a6 */
|
|
|
|
|
load_x x17, 14 * portWORD_SIZE( sp ) /* a7 */
|
|
|
|
|
load_x x18, 15 * portWORD_SIZE( sp ) /* s2 */
|
|
|
|
|
load_x x19, 16 * portWORD_SIZE( sp ) /* s3 */
|
|
|
|
|
load_x x20, 17 * portWORD_SIZE( sp ) /* s4 */
|
|
|
|
|
load_x x21, 18 * portWORD_SIZE( sp ) /* s5 */
|
|
|
|
|
load_x x22, 19 * portWORD_SIZE( sp ) /* s6 */
|
|
|
|
|
load_x x23, 20 * portWORD_SIZE( sp ) /* s7 */
|
|
|
|
|
load_x x24, 21 * portWORD_SIZE( sp ) /* s8 */
|
|
|
|
|
load_x x25, 22 * portWORD_SIZE( sp ) /* s9 */
|
|
|
|
|
load_x x26, 23 * portWORD_SIZE( sp ) /* s10 */
|
|
|
|
|
load_x x27, 24 * portWORD_SIZE( sp ) /* s11 */
|
|
|
|
|
load_x x28, 25 * portWORD_SIZE( sp ) /* t3 */
|
|
|
|
|
load_x x29, 26 * portWORD_SIZE( sp ) /* t4 */
|
|
|
|
|
load_x x30, 27 * portWORD_SIZE( sp ) /* t5 */
|
|
|
|
|
load_x x31, 28 * portWORD_SIZE( sp ) /* t6 */
|
|
|
|
|
addi sp, sp, portCONTEXT_SIZE
|
|
|
|
|
|
|
|
|
|
mret
|
|
|
|
|
.endfunc
|
|
|
|
|
|
|
|
|
|
.align 8
|
|
|
|
|
.func
|
|
|
|
|
xPortStartFirstTask:
|