use none-vector interrupt mode
Signed-off-by: liangkangnan <liangkangnan@163.com>pull/4/head
parent
9e7653a96a
commit
cba47c1f64
|
@ -8,7 +8,6 @@
|
|||
2. 仿真器使用verilator;
|
||||
3. 内部总线使用OBI总线(详细内容见doc/OBI-v1.0.pdf文档);
|
||||
4. 增加指令trace功能;
|
||||
5. 中断模块改进,使用中断向量模式;
|
||||
6. JTAG模块全面改进和优化,支持3个硬件断点,单步等功能,支持gdb调试;
|
||||
7. 增加静态分支预测功能;
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
|
@ -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"
|
|
@ -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;
|
||||
|
|
|
@ -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 )
|
||||
|
|
|
@ -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. */
|
||||
|
|
Loading…
Reference in New Issue