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

View File

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

View File

@ -16,7 +16,7 @@ BIN_TO_MEM := $(BSP_DIR)/../../tools/BinToMem.py
all: $(TARGET) all: $(TARGET)
ASM_SRCS += $(BSP_DIR)/crt0.S 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/utils.c
C_SRCS += $(BSP_DIR)/lib/xprintf.c C_SRCS += $(BSP_DIR)/lib/xprintf.c

View File

@ -37,8 +37,8 @@ _start:
bltu a0, a1, 1b bltu a0, a1, 1b
2: 2:
/* set exception and interrupt vector table */ /* set exception and interrupt entry */
la a0, vector_table la a0, trap_entry
csrw mtvec, a0 csrw mtvec, a0
li a0, 0 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 <task.h>
#include "include/gpio.h" #include "include/gpio.h"
#include "include/utils.h"
/* Set mainCREATE_SIMPLE_BLINKY_DEMO_ONLY to one to run the simple blinky demo, /* 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. */ or 0 to run the more comprehensive test and demo application. */
@ -189,8 +189,7 @@ void vToggleLED( void )
{ {
#ifdef SIMULATION #ifdef SIMULATION
// 运行成功 // 运行成功
asm("li x27, 0x01"); set_test_pass();
asm("li x26, 0x01");
while (1); while (1);
#else #else
GPIO_REG(GPIO_DATA) ^= 0x1; GPIO_REG(GPIO_DATA) ^= 0x1;

View File

@ -38,6 +38,7 @@
#include "string.h" #include "string.h"
#include "include/machine_timer.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 /* 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 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); machine_timer_set_cmp_val(uxTimerIncrementsForOneTick);
#endif #endif
machine_timer_irq_enable(1);// enable timer interrupt machine_timer_irq_enable(1);// enable timer interrupt
rvic_irq_enable(0);
machine_timer_enable(1); // start timer machine_timer_enable(1); // start timer
} }
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
@ -145,6 +147,7 @@ volatile uint32_t ulHartId;
void xPortClearTimerIntPending() void xPortClearTimerIntPending()
{ {
machine_timer_clear_irq_pending(); // clear int pending machine_timer_clear_irq_pending(); // clear int pending
rvic_clear_irq_pending(0);
} }
BaseType_t xPortStartScheduler( void ) 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 portasmRESTORE_ADDITIONAL_REGISTERS macros - which can be defined in a chip
specific version of freertos_risc_v_chip_specific_extensions.h. See the notes specific version of freertos_risc_v_chip_specific_extensions.h. See the notes
at the top of this file. */ at the top of this file. */
#define portCONTEXT_SIZE ( 30 * portWORD_SIZE ) #define portCONTEXT_SIZE ( 28 * portWORD_SIZE )
.global timer_irq_handler .global timer_irq_handler
.global ecall_handler .global ecall_handler
.global xPortStartFirstTask .global xPortStartFirstTask
.global freertos_risc_v_trap_handler .global freertos_risc_v_trap_handler
.global pxPortInitialiseStack .global pxPortInitialiseStack
.extern vector_table
.extern pxCurrentTCB .extern pxCurrentTCB
.extern ulPortTrapHandler .extern ulPortTrapHandler
.extern vTaskSwitchContext .extern vTaskSwitchContext
.extern xTaskIncrementTick .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 xISRStackTop
#.extern portasmHANDLE_INTERRUPT
.extern xPortClearTimerIntPending .extern xPortClearTimerIntPending
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
.align 8
.func .func
freertos_risc_v_trap_handler: freertos_risc_v_trap_handler:
addi sp, sp, -portCONTEXT_SIZE addi sp, sp, -portCONTEXT_SIZE
@ -131,125 +126,18 @@ freertos_risc_v_trap_handler:
store_x x30, 27 * portWORD_SIZE( sp ) store_x x30, 27 * portWORD_SIZE( sp )
store_x x31, 28 * 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 x1, 1 * portWORD_SIZE( sp ) /* ra */
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 x5, 2 * portWORD_SIZE( sp ) /* t0 */ load_x x5, 2 * portWORD_SIZE( sp ) /* t0 */
load_x x6, 3 * portWORD_SIZE( sp ) /* t1 */ load_x x6, 3 * portWORD_SIZE( sp ) /* t1 */
load_x x7, 4 * portWORD_SIZE( sp ) /* t2 */ load_x x7, 4 * portWORD_SIZE( sp ) /* t2 */
@ -281,41 +169,11 @@ processed_source:
mret mret
.endfunc .endfunc
/*-----------------------------------------------------------*/
.align 3 .align 3
.func .func
timer_irq_handler: timer_irq_handler:
addi s1, ra, 0 /* save return address */
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. */ load_x t0, pxCurrentTCB /* Load pxCurrentTCB. */
store_x sp, 0( t0 ) /* Write sp to first TCB member. */ store_x sp, 0( t0 ) /* Write sp to first TCB member. */
@ -337,72 +195,14 @@ not_switch:
load_x t0, 0( sp ) load_x t0, 0( sp )
csrw mepc, t0 csrw mepc, t0
load_x x1, 1 * portWORD_SIZE( sp ) addi ra, s1, 0 /* restore return address */
load_x x5, 2 * portWORD_SIZE( sp ) /* t0 */ ret
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 .endfunc
.align 3 .align 3
.func .func
ecall_handler: ecall_handler:
addi s1, ra, 0 /* save return address */
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. */ load_x t0, pxCurrentTCB /* Load pxCurrentTCB. */
store_x sp, 0( t0 ) /* Write sp to first TCB member. */ store_x sp, 0( t0 ) /* Write sp to first TCB member. */
@ -421,50 +221,15 @@ ecall_handler:
load_x t0, 0( sp ) load_x t0, 0( sp )
csrw mepc, t0 csrw mepc, t0
load_x x1, 1 * portWORD_SIZE( sp ) addi ra, s1, 0 /* restore return address */
load_x x5, 2 * portWORD_SIZE( sp ) /* t0 */ ret
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 .endfunc
.align 8 .align 8
.func .func
xPortStartFirstTask: 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 la t0, freertos_risc_v_trap_handler
csrw mtvec, t0 csrw mtvec, t0
#endif /* portasmHAS_CLILNT */
load_x sp, pxCurrentTCB /* Load pxCurrentTCB. */ load_x sp, pxCurrentTCB /* Load pxCurrentTCB. */
load_x sp, 0( sp ) /* Read sp from first TCB member. */ load_x sp, 0( sp ) /* Read sp from first TCB member. */