What is PLIC interrupt source start and end in interrupt source mapping?

Great to hear @bsvtgc glad all is as expected. Your questions give great inspiration, here is an attempt at answering them.

First, two general ideas to keep in mind:

  • Once set up and configured, and the interrupt-triggering event has been determined, there is no need to mess with CSR’s in the external PLIC handlers – this gives great simplification
  • Upon mret, interrupt will re-trigger endlessly until all enabled devices have been cleared – the device clearing procedures, some are automatic and some are manual, are specific to each device (see below)

How is CSR mip.MEIP set?
Whenever PLIC_PRIORITY[4*source_id] > PLIC_THRESHOLD, and the specific external device block condition is met.

How should CSR mip.MEIP be cleared?
By the three steps of:
reading the source id value from CLAIM/COMPLETE;
clearing the specific external device block condition; and
writing the source id value back to CLAIM/COMPLETE;
in that order.

How is an external interrupt enabled?
By the four general conditions:
CSR mstatus.MIE = 1
CSR mie.MEIE = 1
PLIC_ENABLE[4 * (source_id / 32)].[source_id % 32] = 1
PLIC_PRIORITY[4 * source_id] >= PLIC_THRESHOLD
and, depending on the source id, one of the following specific conditions:
gpio: bit n of input_en is 1; bit(s) n of rise_ie, fall_ie, high_ie, and/or low_ie are 1; bit n of input_val is 1 (either by outside electrical connection, or by bit n of output_en and output_val both being 1, with tri-state or no outside electrical connection); and bit n of iof_en is 0.
pwm: pwmcount >= pwmcmp
spi: (txfifo < txcnt) || (rxfifo > rxcnt)
uart: (txfifo < txcnt) || (rxfifo > rxcnt)
i2c: …
aon rtc: rtcs >= rtccmp
aon wdog: wdogtime >= wdogcmp
aon pmu: …

How do the three different levels of interrupt pending bits all relate?
CSR mip.MEIP – is the cumulative (i.e., inclusive-or’d) result of all external sources;
PLIC core pending bits for each source id – are the individual results of each external device block source;
GPIO block pending bits – are one of the many PLIC core sources, when the corresponding pin multiplexer bit of IOF_EN is 0. Note that the GPIO block pending bits are unavailable and inaccessible when other external device blocks have been routed to the output pins, with the corresponding bit of IOF_EN is 1.

How are the specific device external block pending interrupts cleared?
They all have very different interrupt pending and clearing behavior.
pwm: level sensitive only; ip cleared automatically when count < cmp, or cleared manually when the sticky bit is set and by clearing (i.e., writing 0 to) ip.
uart: level sensitive only; ip cleared automatically when txfifo >= txcnt, and rxfifo <= rxcnt.
spi: level sensitive only; ip cleared automatically when txfifo >= txcnt, and rxfifo <= rxcnt.
gpio: edge or level sensitive; ip cleared manually by setting (i.e., writing 1 to) ip.
aon rtc: level sensitive only; ip cleared automatically when rtccmp < rtcs.
i2c: as suggested by the Manual, see opencores i2c.

2 Likes