use none-vector interrupt mode

Signed-off-by: liangkangnan <liangkangnan@163.com>
pull/4/head
liangkangnan 2021-07-26 09:54:38 +08:00
parent 9e7653a96a
commit cba47c1f64
9 changed files with 157 additions and 401 deletions

View File

@ -8,7 +8,6 @@
2. 仿真器使用verilator
3. 内部总线使用OBI总线(详细内容见doc/OBI-v1.0.pdf文档)
4. 增加指令trace功能
5. 中断模块改进,使用中断向量模式;
6. JTAG模块全面改进和优化支持3个硬件断点单步等功能支持gdb调试
7. 增加静态分支预测功能;

View File

@ -16,11 +16,6 @@
`include "defines.sv"
`define CAUSE_EXCEP_ECALL_M {1'b0, 31'd11}
`define CAUSE_EXCEP_EBREAK_M {1'b0, 31'd3}
`define CAUSE_EXCEP_ILLEGAL_INST_M {1'b0, 31'd2}
`define DCSR_CAUSE_NONE 3'h0
`define DCSR_CAUSE_STEP 3'h4
`define DCSR_CAUSE_DBGREQ 3'h3
@ -109,31 +104,25 @@ module exception (
reg exception_req;
reg[31:0] exception_cause;
reg[31:0] exception_offset;
always @ (*) begin
if (illegal_inst_i) begin
exception_req = 1'b1;
exception_cause = `CAUSE_EXCEP_ILLEGAL_INST_M;
exception_offset = ILLEGAL_INSTR_OFFSET;
exception_cause = 32'h0;
end else if (inst_ecall_i & inst_valid_i) begin
exception_req = 1'b1;
exception_cause = `CAUSE_EXCEP_ECALL_M;
exception_offset = ECALL_OFFSET;
exception_cause = 32'h2;
end else begin
exception_req = 1'b0;
exception_cause = 32'h0;
exception_offset = 32'h0;
end
end
wire int_or_exception_req;
wire[31:0] int_or_exception_cause;
wire[31:0] int_or_exception_offset;
assign int_or_exception_req = (interrupt_req_valid & global_int_en & (~debug_mode_q)) | exception_req;
assign int_or_exception_cause = exception_req ? exception_cause : int_id_i;
assign int_or_exception_offset = exception_req ? exception_offset : INT_OFFSET;
assign int_or_exception_cause = exception_req ? exception_cause : (32'h8 + {24'h0, int_id_i});
wire trigger_matching;
@ -210,7 +199,7 @@ module exception (
csr_we = 1'b1;
csr_waddr = {20'h0, `CSR_MCAUSE};
csr_wdata = int_or_exception_cause;
assert_addr_d = mtvec_i + int_or_exception_offset;
assert_addr_d = mtvec_i;
return_addr_d = inst_addr_i;
state_d = S_W_MSTATUS;
int_id_d = int_id_i;

View File

@ -16,7 +16,7 @@ BIN_TO_MEM := $(BSP_DIR)/../../tools/BinToMem.py
all: $(TARGET)
ASM_SRCS += $(BSP_DIR)/crt0.S
ASM_SRCS += $(BSP_DIR)/vector_table.S
ASM_SRCS += $(BSP_DIR)/trap_entry.S
C_SRCS += $(BSP_DIR)/lib/utils.c
C_SRCS += $(BSP_DIR)/lib/xprintf.c

View File

@ -37,8 +37,8 @@ _start:
bltu a0, a1, 1b
2:
/* set exception and interrupt vector table */
la a0, vector_table
/* set exception and interrupt entry */
la a0, trap_entry
csrw mtvec, a0
li a0, 0

124
sdk/bsp/trap_entry.S Normal file
View File

@ -0,0 +1,124 @@
#define REGBYTES 4
#define STORE sw
#define LOAD lw
.section .text.vector
.align 2
.global trap_entry
.global vector_table
vector_table:
.word illegal_instruction_handler
.word instruction_addr_misaligned_handler
.word ecall_handler
.word ebreak_handler
.word load_misaligned_handler
.word store_misaligned_handler
.word handle_exception_unknown
.word handle_exception_unknown
.word timer_irq_handler
/* add your ISR here */
.weak illegal_instruction_handler
.weak instruction_addr_misaligned_handler
.weak ecall_handler
.weak ebreak_handler
.weak load_misaligned_handler
.weak store_misaligned_handler
.weak handle_exception_unknown
.weak timer_irq_handler
handle_exception_unknown:
j handle_exception_unknown
illegal_instruction_handler:
#ifdef SIMULATION
call sim_ctrl_init
la a0, illegal_instruction_msg
jal ra, xputs
#endif
illegal_instruction_loop:
j illegal_instruction_loop
instruction_addr_misaligned_handler:
j instruction_addr_misaligned_handler
ecall_handler:
j ecall_handler
ebreak_handler:
j ebreak_handler
load_misaligned_handler:
j load_misaligned_handler
store_misaligned_handler:
j store_misaligned_handler
timer_irq_handler:
j timer_irq_handler
/* 异常和中断总入口 */
trap_entry:
addi sp, sp, -32*17
sw x1, 0*4(sp)
sw x5, 1*4(sp)
sw x6, 2*4(sp)
sw x7, 3*4(sp)
sw x10, 4*4(sp)
sw x11, 5*4(sp)
sw x12, 6*4(sp)
sw x13, 7*4(sp)
sw x14, 8*4(sp)
sw x15, 9*4(sp)
sw x16, 10*4(sp)
sw x17, 11*4(sp)
sw x28, 12*4(sp)
sw x29, 13*4(sp)
sw x30, 14*4(sp)
sw x31, 15*4(sp)
/* 保存异常(中断)返回地址 */
csrr x10, mepc
sw x10, 16*4(sp)
/* 使能全局中断 */
csrrsi x0, mstatus, 0x8
/* 读取异常(中断)号 */
csrr a1, mcause
/* 计算偏移地址: id * 4 */
slli a1, a1, 2
la a0, vector_table
add a1, a0, a1
/* 读取异常(中断)处理函数地址 */
lw a1, 0(a1)
/* 跳转到异常(中断)处理函数 */
jalr ra, 0(a1)
/* 恢复异常(中断)返回地址 */
lw x10, 16*4(sp)
csrw mepc, x10
lw x1, 0*4(sp)
lw x5, 1*4(sp)
lw x6, 2*4(sp)
lw x7, 3*4(sp)
lw x10, 4*4(sp)
lw x11, 5*4(sp)
lw x12, 6*4(sp)
lw x13, 7*4(sp)
lw x14, 8*4(sp)
lw x15, 9*4(sp)
lw x16, 10*4(sp)
lw x17, 11*4(sp)
lw x28, 12*4(sp)
lw x29, 13*4(sp)
lw x30, 14*4(sp)
lw x31, 15*4(sp)
addi sp, sp, 32*17
mret
#ifdef SIMULATION
.section .rodata
illegal_instruction_msg:
.string "illegal instruction exception handler entered\n"
#endif

View File

@ -1,123 +0,0 @@
#define REGBYTES 4
#define STORE sw
#define LOAD lw
.section .text.vector
.align 2
.global vector_table
vector_table:
.org 0x00
/* exception */
jal x0, illegal_instruction_handler
jal x0, instruction_addr_misaligned_handler
jal x0, ecall_handler
jal x0, ebreak_handler
jal x0, load_misaligned_handler
jal x0, store_misaligned_handler
jal x0, handle_exception_unknown
jal x0, handle_exception_unknown
/* interrupt */
jal x0, irqs_handler
irqs_vector_table:
.word timer_irq_handler
/* add your ISR here */
.weak illegal_instruction_handler
.weak instruction_addr_misaligned_handler
.weak ecall_handler
.weak ebreak_handler
.weak load_misaligned_handler
.weak store_misaligned_handler
.weak handle_exception_unknown
.weak timer_irq_handler
handle_exception_unknown:
j handle_exception_unknown
illegal_instruction_handler:
#ifdef SIMULATION
call sim_ctrl_init
la a0, illegal_instruction_msg
jal ra, xputs
#endif
illegal_instruction_loop:
j illegal_instruction_loop
instruction_addr_misaligned_handler:
j instruction_addr_misaligned_handler
ecall_handler:
j ecall_handler
ebreak_handler:
j ebreak_handler
load_misaligned_handler:
j load_misaligned_handler
store_misaligned_handler:
j store_misaligned_handler
timer_irq_handler:
j timer_irq_handler
irqs_handler:
addi sp, sp, -32*17
sw x1, 0*4(sp)
sw x5, 1*4(sp)
sw x6, 2*4(sp)
sw x7, 3*4(sp)
sw x10, 4*4(sp)
sw x11, 5*4(sp)
sw x12, 6*4(sp)
sw x13, 7*4(sp)
sw x14, 8*4(sp)
sw x15, 9*4(sp)
sw x16, 10*4(sp)
sw x17, 11*4(sp)
sw x28, 12*4(sp)
sw x29, 13*4(sp)
sw x30, 14*4(sp)
sw x31, 15*4(sp)
csrr a0, mepc
sw a0, 16*4(sp)
/* 使能全局中断 */
csrrsi x0, mstatus, 0x8
/* 读取中断号 */
csrr a1, mcause
/* 计算偏移地址: id * 4 */
slli a1, a1, 2
la a0, irqs_vector_table
add a1, a0, a1
/* 读取中断处理函数地址 */
lw a1, 0(a1)
/* 跳转到中断处理函数 */
jalr ra, 0(a1)
lw a0, 16*4(sp)
csrw mepc, a0
lw x1, 0*4(sp)
lw x5, 1*4(sp)
lw x6, 2*4(sp)
lw x7, 3*4(sp)
lw x10, 4*4(sp)
lw x11, 5*4(sp)
lw x12, 6*4(sp)
lw x13, 7*4(sp)
lw x14, 8*4(sp)
lw x15, 9*4(sp)
lw x16, 10*4(sp)
lw x17, 11*4(sp)
lw x28, 12*4(sp)
lw x29, 13*4(sp)
lw x30, 14*4(sp)
lw x31, 15*4(sp)
addi sp, sp, 32*17
mret
.section .rodata
illegal_instruction_msg:
.string "illegal instruction exception handler entered\n"

View File

@ -53,7 +53,7 @@
#include <task.h>
#include "include/gpio.h"
#include "include/utils.h"
/* Set mainCREATE_SIMPLE_BLINKY_DEMO_ONLY to one to run the simple blinky demo,
or 0 to run the more comprehensive test and demo application. */
@ -189,8 +189,7 @@ void vToggleLED( void )
{
#ifdef SIMULATION
// 运行成功
asm("li x27, 0x01");
asm("li x26, 0x01");
set_test_pass();
while (1);
#else
GPIO_REG(GPIO_DATA) ^= 0x1;

View File

@ -38,6 +38,7 @@
#include "string.h"
#include "include/machine_timer.h"
#include "include/rvic.h"
/* Let the user override the pre-loading of the initial LR with the address of
prvTaskExitError() in case it messes up unwinding of the stack in the
@ -138,6 +139,7 @@ volatile uint32_t ulHartId;
machine_timer_set_cmp_val(uxTimerIncrementsForOneTick);
#endif
machine_timer_irq_enable(1);// enable timer interrupt
rvic_irq_enable(0);
machine_timer_enable(1); // start timer
}
/*-----------------------------------------------------------*/
@ -145,6 +147,7 @@ volatile uint32_t ulHartId;
void xPortClearTimerIntPending()
{
machine_timer_clear_irq_pending(); // clear int pending
rvic_clear_irq_pending(0);
}
BaseType_t xPortStartScheduler( void )

View File

@ -78,27 +78,22 @@ registers must be saved by the portasmSAVE_ADDITIONAL_REGISTERS and
portasmRESTORE_ADDITIONAL_REGISTERS macros - which can be defined in a chip
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 )
#define portCONTEXT_SIZE ( 28 * portWORD_SIZE )
.global timer_irq_handler
.global ecall_handler
.global xPortStartFirstTask
.global freertos_risc_v_trap_handler
.global pxPortInitialiseStack
.extern vector_table
.extern pxCurrentTCB
.extern ulPortTrapHandler
.extern vTaskSwitchContext
.extern xTaskIncrementTick
#.extern Timer_IRQHandler
#.extern pullMachineTimerCompareRegister
#.extern pullNextTime
#.extern uxTimerIncrementsForOneTick /* size_t type so 32-bit on 32-bit core and 64-bits on 64-bit core. */
.extern xISRStackTop
#.extern portasmHANDLE_INTERRUPT
.extern xPortClearTimerIntPending
/*-----------------------------------------------------------*/
.align 8
.func
freertos_risc_v_trap_handler:
addi sp, sp, -portCONTEXT_SIZE
@ -131,125 +126,18 @@ freertos_risc_v_trap_handler:
store_x x30, 27 * portWORD_SIZE( sp )
store_x x31, 28 * portWORD_SIZE( sp )
csrr t0, mstatus /* Required for MPIE bit. */
store_x t0, 29 * portWORD_SIZE( sp )
/* 读取异常(中断)号 */
csrr a1, mcause
/* 计算偏移地址: id * 4 */
slli a1, a1, 2
la a0, vector_table
add a1, a0, a1
/* 读取异常(中断)处理函数地址 */
lw a1, 0(a1)
/* 跳转到异常(中断)处理函数 */
jalr ra, 0(a1)
portasmSAVE_ADDITIONAL_REGISTERS /* Defined in freertos_risc_v_chip_specific_extensions.h to save any registers unique to the RISC-V implementation. */
load_x t0, pxCurrentTCB /* Load pxCurrentTCB. */
store_x sp, 0( t0 ) /* Write sp to first TCB member. */
csrr a0, mcause
csrr a1, mepc
test_if_asynchronous:
srli a2, a0, __riscv_xlen - 1 /* MSB of mcause is 1 if handing an asynchronous interrupt - shift to LSB to clear other bits. */
beq a2, x0, handle_synchronous /* Branch past interrupt handing if not asynchronous. */
store_x a1, 0( sp ) /* Asynch so save unmodified exception return address. */
handle_asynchronous:
#if 0
#if( portasmHAS_MTIME != 0 )
test_if_mtimer: /* If there is a CLINT then the mtimer is used to generate the tick interrupt. */
addi t0, x0, 1
slli t0, t0, __riscv_xlen - 1 /* LSB is already set, shift into MSB. Shift 31 on 32-bit or 63 on 64-bit cores. */
addi t1, t0, 7 /* 0x8000[]0007 == machine timer interrupt. */
bne a0, t1, test_if_external_interrupt
load_x t0, pullMachineTimerCompareRegister /* Load address of compare register into t0. */
load_x t1, pullNextTime /* Load the address of ullNextTime into t1. */
#if( __riscv_xlen == 32 )
/* Update the 64-bit mtimer compare match value in two 32-bit writes. */
li t4, -1
lw t2, 0(t1) /* Load the low word of ullNextTime into t2. */
lw t3, 4(t1) /* Load the high word of ullNextTime into t3. */
sw t4, 0(t0) /* Low word no smaller than old value to start with - will be overwritten below. */
sw t3, 4(t0) /* Store high word of ullNextTime into compare register. No smaller than new value. */
sw t2, 0(t0) /* Store low word of ullNextTime into compare register. */
lw t0, uxTimerIncrementsForOneTick /* Load the value of ullTimerIncrementForOneTick into t0 (could this be optimized by storing in an array next to pullNextTime?). */
add t4, t0, t2 /* Add the low word of ullNextTime to the timer increments for one tick (assumes timer increment for one tick fits in 32-bits). */
sltu t5, t4, t2 /* See if the sum of low words overflowed (what about the zero case?). */
add t6, t3, t5 /* Add overflow to high word of ullNextTime. */
sw t4, 0(t1) /* Store new low word of ullNextTime. */
sw t6, 4(t1) /* Store new high word of ullNextTime. */
#endif /* __riscv_xlen == 32 */
#if( __riscv_xlen == 64 )
/* Update the 64-bit mtimer compare match value. */
ld t2, 0(t1) /* Load ullNextTime into t2. */
sd t2, 0(t0) /* Store ullNextTime into compare register. */
ld t0, uxTimerIncrementsForOneTick /* Load the value of ullTimerIncrementForOneTick into t0 (could this be optimized by storing in an array next to pullNextTime?). */
add t4, t0, t2 /* Add ullNextTime to the timer increments for one tick. */
sd t4, 0(t1) /* Store ullNextTime. */
#endif /* __riscv_xlen == 64 */
load_x sp, xISRStackTop /* Switch to ISR stack before function call. */
jal xTaskIncrementTick
beqz a0, processed_source /* Don't switch context if incrementing tick didn't unblock a task. */
jal vTaskSwitchContext
j processed_source
test_if_external_interrupt: /* If there is a CLINT and the mtimer interrupt is not pending then check to see if an external interrupt is pending. */
addi t1, t1, 4 /* 0x80000007 + 4 = 0x8000000b == Machine external interrupt. */
bne a0, t1, as_yet_unhandled /* Something as yet unhandled. */
#endif /* portasmHAS_MTIME */
#endif
/* TODO: 判断是定时器中断还是其他(外部)中断 */
load_x sp, xISRStackTop /* Switch to ISR stack before function call. */
call xPortClearTimerIntPending
jal xTaskIncrementTick
beqz a0, processed_source /* Don't switch context if incrementing tick didn't unblock a task. */
jal vTaskSwitchContext
#jal portasmHANDLE_INTERRUPT /* Jump to the interrupt handler if there is no CLINT or if there is a CLINT and it has been determined that an external interrupt is pending. */
j processed_source
handle_synchronous:
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. */
test_if_environment_call:
li t0, 11 /* 11 == environment call. */
bne a0, t0, is_exception /* Not an M environment call, so some other exception. */
load_x sp, xISRStackTop /* Switch to ISR stack before function call. */
jal vTaskSwitchContext
j processed_source
is_exception:
csrr t0, mcause /* For viewing in the debugger only. */
csrr t1, mepc /* For viewing in the debugger only */
csrr t2, mstatus
j is_exception /* No other exceptions handled yet. */
as_yet_unhandled:
csrr t0, mcause /* For viewing in the debugger only. */
j as_yet_unhandled
processed_source:
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
portasmRESTORE_ADDITIONAL_REGISTERS /* Defined in freertos_risc_v_chip_specific_extensions.h to restore any registers unique to the RISC-V implementation. */
/* Load mstatus with the interrupt enable bits used by the task. */
load_x t0, 29 * portWORD_SIZE( sp )
csrw mstatus, t0 /* Required for MPIE bit. */
load_x x1, 1 * portWORD_SIZE( sp )
load_x x1, 1 * portWORD_SIZE( sp ) /* ra */
load_x x5, 2 * portWORD_SIZE( sp ) /* t0 */
load_x x6, 3 * portWORD_SIZE( sp ) /* t1 */
load_x x7, 4 * portWORD_SIZE( sp ) /* t2 */
@ -281,41 +169,11 @@ processed_source:
mret
.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 )
addi s1, ra, 0 /* save return address */
load_x t0, pxCurrentTCB /* Load pxCurrentTCB. */
store_x sp, 0( t0 ) /* Write sp to first TCB member. */
@ -337,72 +195,14 @@ not_switch:
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
addi ra, s1, 0 /* restore return address */
ret
.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 )
addi s1, ra, 0 /* save return address */
load_x t0, pxCurrentTCB /* Load pxCurrentTCB. */
store_x sp, 0( t0 ) /* Write sp to first TCB member. */
@ -421,50 +221,15 @@ ecall_handler:
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
addi ra, s1, 0 /* restore return address */
ret
.endfunc
.align 8
.func
xPortStartFirstTask:
#if( portasmHAS_SIFIVE_CLINT != 0 )
/* If there is a clint then interrupts can branch directly to the FreeRTOS
trap handler. Otherwise the interrupt controller will need to be configured
outside of this file. */
la t0, freertos_risc_v_trap_handler
csrw mtvec, t0
#endif /* portasmHAS_CLILNT */
load_x sp, pxCurrentTCB /* Load pxCurrentTCB. */
load_x sp, 0( sp ) /* Read sp from first TCB member. */