A low-latency vectored interrupt mode is available, which allows the
Interrupt Controller to directly supply the interrupt vector for each individual
interrupt (using the input port Interrupt_Address). The
address of all interrupt handlers, including interrupts that are using the trap-vector
base-address in mtvec, must be passed to the Interrupt Controller when initializing the
interrupt system. When a particular interrupt occurs, this address is supplied by the
Interrupt Controller, which allows MicroBlaze V to
directly jump to the handler code. The interrupt address must remain valid until MicroBlaze V has taken the interrupt and jumped to the
address.
With this mode, MicroBlaze V also directly
sends the appropriate interrupt acknowledge to the Interrupt Controller (using the
Interrupt_Ack output port), although it is still
the responsibility of the interrupt service routine to acknowledge level sensitive
interrupts at the source.
This information allows the Interrupt Controller to acknowledge interrupts appropriately, both for level-sensitive and edge-triggered interrupts.
To inform the Interrupt Controller of the interrupt handling events,
Interrupt_Ack is set to:
- 01
- When MicroBlaze V jumps to the interrupt handler code.
- 10
- When the MRET instruction is executed.
- 11
- When the global interrupt enable bit MIE in mstatus is changed from 0 to 1, which enables interrupts again.
The Interrupt_Ack output port is active
during one clock cycle, and is then reset to 00.
With low-latency interrupt mode, control is directly passed to the interrupt handler for each individual interrupt utilizing this mode. In this case, it is the responsibility of each handler to save and restore used registers. This can be achieved with the RISC-V GCC compiler using the following code:
/* Declare a low-latency interrupt handler */
void interrupt_handler_name() __attribute__((aligned(4), interrupt));
Equivalent Pseudocode
mepc ← PC
if C_USE_INTERRUPT = 2
PC ← Interrupt_Address
Interrupt_Ack ← 01
else
PC ← mtvec
mcause ← 0x8000000B
mstatus.mpie ← mstatus.mie
mstatus.mie ← 0
if C_USE_MMU > 0
mstatus.mpp ← privilege mode
else
mstatus.mpp ← 11
mtval ← 0
Reservation ← 0