在RISC-V手册第二卷中说:
当MODE = Vectored时,所有同步异常进入机器模式会导致将pc设置为BASE字段中的地址,而interrupts导致将pc设置为BASE字段中的地址。再加上中断原因编号的四倍。
同步异常处理程序是否与ID = 0中断处理程序(用户软件中断)相同?我尝试解决有关qemu-system-riscv64 virt的问题,并按照以下步骤尝试测试异常,用户软件中断和机器计时器中断:
# boot:
la t0, __vector_table
xor t0, t0, 1 # vector mode
csrw mtvec, t0
# vector table
__vector_table:
IRQ_0:
j trap_handler_entry
IRQ_1:
j trap_handler_entry
...
IRQ_7:
j timer_interrupt_vector_handler
# handler at vector table index 0
trap_handler_entry:
SAVE_REGISTER
j trap_handler # trap_handler is the handler
# I used to handle all trap in direct mode
RESTORE_REGISTER
mret
# timer handler
void __atrributr__ ((interrupt)) timer_interrupt_vector_handler {
add new value in mtimecmp
}
此时,我测试ecall和定时器中断,当定时器中断和ecall发生时,它肯定会进入向量表中的函数,ecall-> INDEX = 0,定时器-> INDEX = 7然后,我尝试触发用户软件中断,例如:
# Test function
while(1) {
if (odd round) { ecall }
else {
set_csr(mip, USIP);
/* Test func in M mode, enable USIE in MIE,
* and other interrupts works well */
}
}
但是没有用户软件中断发生,该手册说:
每个较低的特权级别都有一个单独的软件挂起等待位(SSIP,USIP),CSR访问可以从相关或更高特权级别的本地暂存器上运行的代码对CSR访问进行读写。
而且我确信我可以通过设置MIP_SSIP来获得Supervisor软件中断。我在Spike中检查了中断引发功能,发现没有用户软件中断。该手册还说:
如果不支持用户级中断,则将USIP和USIE硬接线为零。
所以我打印了mie来对其进行处理:
# config in mie and mstatus
write_csr(mie, read_csr(mie) | MIP_MTIP | MIP_MSIP | MIP_SSIP | MIP_USIP);
write_csr(mstatus, (read_csr(mstatus) | MSTATUS_MIE | MSTATUS_SIE | MSTATUS_UIE));
# Set mie and mip in test func
set_csr(mie, MIP_USIP);
set_csr(mip, MIP_USIP);
# Result before and after set
MIE >> 000000000000008a # before
MIP >> 0000000000000000
MIE >> 000000000000008a # after
MIP >> 0000000000000000
USIP和USIE固定为零!那么,也许现在没有USI?但是取决于第一次尝试,我认为使用ID = 0中断处理程序(用户软件中断)确实执行了同步异常。看来我的问题的答案可能是肯定的,并且没有用户软件中断就能避免冲突?这是正确的吗?有冲突吗?
USIP和USIE硬连线为零是实现细节。 第II卷:RISC-V特权体系结构V1.10