Peripheral Interrupt Procedure in RISC-V
Last updated on April 2, 2023 pm
Peripheral Interrupt Procedure in RISC-V
The procedure of peripheral interrupt in RISC-V is quite complicated and multi-layered.
Basically, all peripheral interrupts are reported to platform-level interrupt controller or PLIC, which is similar to PIC (programmable interrupt controller) in x86 architecture.
The memory mapped from PLIC varied by platforms. Chapter 3 of official PLIC Specification gives a sample. In QEMU, it could be found under qemu/include/hw/riscv
folder.
Registers
There are (five types of) registers for PLIC:
priority
pending
enable
threshold
claim
/complete
Priorities
The priorities of external interrupts are defined in priority
registers, whose ranges from 1
to 1023
(1023 sources in total, also known as interrupt identifiers, ID). Note that 0
is reserved for no interrupt occurring.
1 interrupt source maps to 1 register. For example,
Address | Mapping |
---|---|
base + 0x0000 |
Reserved |
base + 0x0004 |
priority value of Interrupt source 1 |
base + 0x0008 |
priority value of Interrupt source 2 |
… | … |
base + 0x0FFC |
priority value of Interrupt source 1023 |
The value in the priority
is the priority level of mapped resource. 0
is representing never interrupt, and the larger the higher priority.
If two interrupt resources have the same priority level, PLIC will get the smallest ID first and give the interrupt to Hart to handle.
QEMU Specific
QEMU’s RISC-V virtual machine virt
supports 7 levels of priority.
In its create_pcie_irq_map
function, it set that
1 |
|
qemu_fdt_setprop_cells
is a function-like macro defined in qemu/include/sysemu/device_tree.h
, helping set up. fdt
stands for flattened device tree and represents the device tree blob pointer. And prop
means properties. It treats interrupt-map-mask
as a property whit smallest value 0
and biggest value 7
.
Pending
Each bit of pending
corresponds to one interrupt source, 1
for interrupt happening.
Interrupt Flow
When external interrupts come in:
- PLIC checks their
priority
- if same, get the one with the smallest interrupt source ID
- PLIC checks
enable
- PLIC checks is the
priority
bigger thanthreshold
- PLIC sets corresponding
pending
- HART’s running is interrupted and starts to handle the interrupt
- HART reads value from
claim
to know interrupt source ID - HART calls corresponding functions
- HART writes back to
complete
- HART returns to normal running
- PLIC cleans the
pending
Initialization
- Define interrupt source ID
- Set
priority
- Set
enable
- Set
threshold
- Set
MIE
bit inmstatus
, M-mode global interrupt-enable bit (for M-mode) - Set
MEIE
bit inmie
, machine-level external interrupts enable bit in machine interrupt enable register.
References
- riscv/riscv-plic-spec: PLIC Specification
- [完结] 循序渐进,学习开发一个RISC-V上的操作系统 - 汪辰 - 2021春:第11章-外部设备中断_哔哩哔哩_bilibili
- Interrupts - Beginner’s Guide to PIC Programming - picguides.com
- mini-riscv-os/07-ExterInterrupt.md at master · cccriscv/mini-riscv-os
- PLIC - OSDev Wiki
- 8259 PIC - OSDev Wiki
- 2 4 RISC V::中斷與異常處理 中斷篇 · ianchen0119/AwesomeCS Wiki
- 2 5 RISC V::中斷與異常處理 PLIC 介紹 · ianchen0119/AwesomeCS Wiki