Reputation: 185
In RISC-V Manual Volume II, it said:
When MODE=Vectored, all synchronous exceptions into machine mode cause the pc to be set to the address in the BASE field, whereas interrupts cause the pc to be set to the address in the BASE field plus four times the interrupt cause number.
Does the synchronous exception handler is same with the ID=0 interrupt handler(User software interrupt) ? And I try to solve my question on qemu-system-riscv64 virt, and my steps following, I try to test exception, user software interrupt and machine timer interrupt:
# 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
}
At this point I test ecall and timer interrupt, when timer interrupt and ecall happens it surely go to the function in vector table, ecall -> INDEX=0, timer -> INDEX=7 And then I try to trigger a user software interrupt, like:
# 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 */
}
}
But there no user software interrupt happens, the manual saids:
Each lower privilege level has a separate software interrupt-pending bit (SSIP, USIP), which can be both read and written by CSR accesses from code running on the local hart at the associated or any higher privilege level.
And I'm sure I can get Supervisor Software Interrupt by set MIP_SSIP. And I check the interrupt raise function in Spike, I found that there is no user softeware interrupt ... The manual also said:
If user-level interrupts are not supported, USIP and USIE are hardwired to zero.
So I print the mie to ckeck it:
# 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
The USIP and USIE are hardwired to zero ! So, maybe there is no USI right now ? But depends on the first try, I think synchronous exception actully using the ID=0 interrupt handler(User software interrupt). It seems may the answer of my question is yes ... And the conflict is avoid by no user software interrupt ? Is this right? Does there any conflict ?
Upvotes: 1
Views: 919
Reputation: 76
The answer made by @eyck is a very good description.
A Word About Values and Alignments:
In vectored interrupt mode, note that the BASE field of mtvec
is only 25 bits, not 30 bits as in with the direct (non-vectored) interrupt mode. Thus, BASE must be a 128-bit (16-Byte) aligned number -- not 64-bit aligned as stated in some manuals or other documentation. The "OFFS" field (my term) of mtvec
is 5 bits, which comprises the five bits (decoded values 0 thru 31) of the Exception Code from mcause
, specifically mcause[4:0]
. Since the MODE field of mtvec
occupies the lowest two bits of this register value, the final address targeted by mtvec
must be 32-bit (4-Byte) aligned.
Thus, mtvec[31:2]
must always be 4-Byte aligned, in any event (exception and interrupt) handling mode; and in case of vectored mode, its BASE portion must be 128-bit aligned, because it is at mtvec[31:7]
.
Said another way, for the mtvec
CSR,
mtvec[1:0]=MODE (0=direct, 1=vectored)
mtvec[6:2]=OFFS (0=direct/vectored-sync, mcause[4:0]=vectored-async)
mtvec[31:7]=BASE (128-bit aligned)
and for the mcause
CSR
mcause[4:0]=exception-code (prio 31 highest, 0 lowest)
mcause[30:5]=reserved
mcause[31]=event (0=synch-exception, 1=async-interrupt)
Last, when arranging the vector table, be very careful to make each entry on a 4-Byte boundary. Either specify .align 2
(or .balign 4
), or make sure the assembler does not emit compressed (16-bit) forms of the jump instruction. You can momentarily turn off use of compressed forms with .option norvc
. For best results, do this between .option push
and .option pop
.
Upvotes: 0
Reputation: 36
USIP and USIE hardwired to zero is an implementation detail. The Volume II: RISC-V Privileged Architectures V1.10 states:
When vectored interrupts are enabled, interrupt cause 0, which corresponds to user-mode soft- ware interrupts, are vectored to the same location as synchronous exceptions. This ambiguity does not arise in practice, since user-mode software interrupts are either disabled or delegated to a less-privileged mode.
So basically the anser is yes, the synchronous exception handler is same as the user software interrupt interrupt handler.
Upvotes: 2