diff --git a/README.md b/README.md index 4700b93..cb0c422 100644 --- a/README.md +++ b/README.md @@ -8,7 +8,6 @@ 2. 仿真器使用verilator; 3. 内部总线使用OBI总线(详细内容见doc/OBI-v1.0.pdf文档); 4. 增加指令trace功能; -5. 中断模块改进,使用中断向量模式; 6. JTAG模块全面改进和优化,支持3个硬件断点,单步等功能,支持gdb调试; 7. 增加静态分支预测功能; diff --git a/rtl/core/exception.sv b/rtl/core/exception.sv index 9be50ca..8e7d468 100644 --- a/rtl/core/exception.sv +++ b/rtl/core/exception.sv @@ -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_req = (interrupt_req_valid & global_int_en & (~debug_mode_q)) | exception_req; + 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; diff --git a/sdk/bsp/bsp.mk b/sdk/bsp/bsp.mk index aab4e84..bdd770f 100644 --- a/sdk/bsp/bsp.mk +++ b/sdk/bsp/bsp.mk @@ -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 diff --git a/sdk/bsp/crt0.S b/sdk/bsp/crt0.S index adaf944..b009a46 100644 --- a/sdk/bsp/crt0.S +++ b/sdk/bsp/crt0.S @@ -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 diff --git a/sdk/bsp/trap_entry.S b/sdk/bsp/trap_entry.S new file mode 100644 index 0000000..5556e07 --- /dev/null +++ b/sdk/bsp/trap_entry.S @@ -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 diff --git a/sdk/bsp/vector_table.S b/sdk/bsp/vector_table.S deleted file mode 100644 index 50e7252..0000000 --- a/sdk/bsp/vector_table.S +++ /dev/null @@ -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" diff --git a/sdk/examples/freertos/Demo/tinyriscv_GCC/main.c b/sdk/examples/freertos/Demo/tinyriscv_GCC/main.c index 8bee5ed..7f1ed8d 100644 --- a/sdk/examples/freertos/Demo/tinyriscv_GCC/main.c +++ b/sdk/examples/freertos/Demo/tinyriscv_GCC/main.c @@ -53,7 +53,7 @@ #include #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; diff --git a/sdk/examples/freertos/Source/portable/RISC-V/port.c b/sdk/examples/freertos/Source/portable/RISC-V/port.c index 5fddbbf..c444f73 100644 --- a/sdk/examples/freertos/Source/portable/RISC-V/port.c +++ b/sdk/examples/freertos/Source/portable/RISC-V/port.c @@ -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 ) diff --git a/sdk/examples/freertos/Source/portable/RISC-V/portASM.S b/sdk/examples/freertos/Source/portable/RISC-V/portASM.S index 09ec4b2..3b19237 100644 --- a/sdk/examples/freertos/Source/portable/RISC-V/portASM.S +++ b/sdk/examples/freertos/Source/portable/RISC-V/portASM.S @@ -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 */ @@ -280,42 +168,12 @@ processed_source: addi sp, sp, portCONTEXT_SIZE mret - .endfunc -/*-----------------------------------------------------------*/ + .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. */