After chatting with some vendors in the RISC-V community and learning a bit of the story behind this, I wanted to suggest a revision to the PLIC spec to remove some ambiguity.
The spec states that interrupt gateways can be level or edge triggered. Some implementations use a fully static configuration that is non-configurable and only supports e.g. level triggers. This might be fine for certain controllers. For more general-purpose designs, many customers require both level and edge triggering, as well as runtime configuration (high / low, rising / falling / both) of individual interrupts.
Many vendors have populated those registers at offset 0x1080, based on (IIRC) SIFive's work. In some cases, those registers are read-only (registers are for informational purposes only), while in other designs, the registers are writeable. In some cases, the registers are there but they are undocumented (even in the vendor data sheet).
This results in some fragmentation (especially noticeable with new, vendor-specific Devicetree bindings). From a firmware / kernel perspective, we don't want 1000 flavours of PLIC drivers. We want a single driver with 1 main Devicetree compatible. It's still OK for vendors to differentiate their interrupt gateways via functionality encoded in other mapped registers. But for the basics (which includes interrupt trigger configuration), it would be great to have a main compatible. We don't want RISC-V's Devicetree bindings to be deprecated, it should be more or less authoritative.
In any case, It would be very much in the interest of the community to remove this ambiguity from the RISC-V PLIC spec. So I would recommend at least the following
- naming the address range in the memory map
- outlining the desired functionality of those registers if they are implemented
- bumping the revision of the PLIC spec
- ensuring that vendors are aware that they must document how their interrupt gateway behaves.
There are other ways of doing this as well, but the above is the least invasive way that I can think of. It also allows existing vendors to continue with business as usual.
Other ways to solve this are runtime oriented
- an ID register (mentioned already in #40) with some bits set aside to enumerate the trigger control type
- writing and reading back a bit pattern on init (mentioned in #51)
The latter runtime approach depends on read / write semantics (is a fault triggered on write to reserved memory? Are writes ignored?). This is kind of a slippery-slope approach.
The ID register is at least something that can be queried during bringup and encoded offline (we don't want to add extra cycles to interrupt processing). However, that is an invasive change, because it is not backwards-compatible and requires a new register added to the memory map.
Obviously though, if vendors are required to clearly document the type of interrupt trigger configuration / control in their implementation, that should be fine (assuming one always knows the PLIC implementation). From the Devicetree perspective, this is just an enumeration, and a new PLIC spec revision could be made that is backward compatible.
However, in the case of a generic PLIC driver for e.g. Linux, where one does not know who implemented the PLIC or its characteristics, reading a few bits from an ID register at runtime would be the easiest / safest way.