What the PLIC does (pg 72) is take level and edge sensitive interrupts and convert them into interrupt requests in PLIC ‘gateways’; the gateways must be memory-mapped from the processor, as each interrupt they present to the PLIC core must be acknowledged with some ‘interrupt completion message’. The spec does not provide details of an ‘interrupt completion message’, nor the memory map for any of this: it does note (pg 75) that an interrupt completion message is usually ‘ a write to a non-idempotent memory-mapped I/O control register’.
PCIe style MSI/MSI-X interrupt messages can be treated similarly to edge sensitive interrupts at a suitable PLIC gateway.
The PLIC core assigns a priority to each PLIC gateway input, and has selectable enables for each RISC-V ‘target’ (presumable a RISC-V hart) for each PLIC gateway input, and an interrupt threshold value for each target.
A target has its ‘external interrupt pending’ bit set if any of the PLIC gateways whose interrupts are enabled for the target are requesting an interrupt at a priority level greater than the threshold.
Priority levels start at 0 - actually meaning ‘never interrupt’ and go up.
If two PLIC gateways are requesting an interrupt at the same priority level for a specific target then the lowest numbered gateway is selected (gateways are numbered 1 upwards).
The PLIC core must provide access to an ‘interrupt claim’ register for a target that can be read to yield the ‘id’ of the selected gateway, atomically clearing the interrupt pending bit in the PLIC core for that gateway.
The interrupt routine must, if the id is not 0, handle the interrupt and then issue a completion to the gateway, which may then reassert the pending bit in the PLIC core.
Although the spec does not prescribe a PLIC register layout and so on, there is the standard RISC-V implementation problem here of - if it ain’t compatible with RocketChip, you’re on you’re own. For example, I’ve just been digging in to Zephyr; basically it assumes a PLIC unless you are qemu. And by PLIC, it means ‘the rocket-chip PLIC’. So whatever register layout it has (I have not dug in to that yet), you need too.
Summary of the PLIC
The PLIC needs to be memory mapped with a ‘gateway’ for each external interrupt source; each gateway expects a single wire that may be edge or level triggered depending on the gateway type. The gateways are also memory-mapped.
The PLIC is not required from what I can see if there are zero or one external interrupt sources.
In my mind a PLIC is not required for a microcontroller with few interrupts: it increases the silicon complexity, complicates the software (with associated die impact in SRAM size).
Whether that would end up being ‘compliant’ is probably moot - for low end micro controllers being platform compliant is way less important than cost.
In summary, a RISC-V hart requires a single level-sensitive external interrupt line which gets to the xEIP bits, or nothing if you have no interrupt support; if you have more than one interrupt source, the spec may required a PLIC.