Garret Kelly | 9eebde0 | 2019-10-22 15:36:49 -0400 | [diff] [blame] | 1 | --- |
| 2 | title: "Interrupt Controller Technical Specification" |
| 3 | --- |
lowRISC Contributors | 802543a | 2019-08-31 12:12:56 +0100 | [diff] [blame] | 4 | |
Garret Kelly | 9eebde0 | 2019-10-22 15:36:49 -0400 | [diff] [blame] | 5 | # Overview |
lowRISC Contributors | 802543a | 2019-08-31 12:12:56 +0100 | [diff] [blame] | 6 | |
| 7 | This document specifies the Interrupt Controller (RV_PLIC) functionality. This |
| 8 | module conforms to the |
Timothy Chen | e464899 | 2019-11-02 17:58:54 -0700 | [diff] [blame] | 9 | [Comportable guideline for peripheral functionality]({{< relref "doc/rm/comportability_specification" >}}). |
lowRISC Contributors | 802543a | 2019-08-31 12:12:56 +0100 | [diff] [blame] | 10 | See that document for integration overview within the broader top level system. |
| 11 | |
lowRISC Contributors | 802543a | 2019-08-31 12:12:56 +0100 | [diff] [blame] | 12 | |
Garret Kelly | 9eebde0 | 2019-10-22 15:36:49 -0400 | [diff] [blame] | 13 | ## Features |
lowRISC Contributors | 802543a | 2019-08-31 12:12:56 +0100 | [diff] [blame] | 14 | |
| 15 | - RISC-V Platform-Level Interrupt Controller (PLIC) compliant interrupt controller |
Eunchan Kim | 88a8615 | 2020-04-13 16:12:08 -0700 | [diff] [blame] | 16 | - Support arbitrary number of interrupt vectors (up to 255) and targets |
lowRISC Contributors | 802543a | 2019-08-31 12:12:56 +0100 | [diff] [blame] | 17 | - Support interrupt enable, interrupt status registers |
Greg Chadwick | 828e9d1 | 2019-10-23 11:37:24 +0100 | [diff] [blame] | 18 | - Memory-mapped MSIP register per HART for software interrupt control. |
lowRISC Contributors | 802543a | 2019-08-31 12:12:56 +0100 | [diff] [blame] | 19 | |
Garret Kelly | 9eebde0 | 2019-10-22 15:36:49 -0400 | [diff] [blame] | 20 | ## Description |
lowRISC Contributors | 802543a | 2019-08-31 12:12:56 +0100 | [diff] [blame] | 21 | |
| 22 | The RV_PLIC module is designed to manage various interrupt sources from the |
Greg Chadwick | 828e9d1 | 2019-10-23 11:37:24 +0100 | [diff] [blame] | 23 | peripherals. It receives interrupt events as either edge or level of the |
| 24 | incoming interrupt signals (``intr_src_i``) and can notify multiple targets. |
lowRISC Contributors | 802543a | 2019-08-31 12:12:56 +0100 | [diff] [blame] | 25 | |
Garret Kelly | 9eebde0 | 2019-10-22 15:36:49 -0400 | [diff] [blame] | 26 | ## Compatibility |
lowRISC Contributors | 802543a | 2019-08-31 12:12:56 +0100 | [diff] [blame] | 27 | |
| 28 | The RV_PLIC is compatible with any RISC-V core implementing the RISC-V privilege specification. |
| 29 | |
Garret Kelly | 9eebde0 | 2019-10-22 15:36:49 -0400 | [diff] [blame] | 30 | # Theory of Operations |
lowRISC Contributors | 802543a | 2019-08-31 12:12:56 +0100 | [diff] [blame] | 31 | |
Garret Kelly | 9eebde0 | 2019-10-22 15:36:49 -0400 | [diff] [blame] | 32 | ## Block Diagram |
lowRISC Contributors | 802543a | 2019-08-31 12:12:56 +0100 | [diff] [blame] | 33 | |
| 34 |  |
| 35 | |
Timothy Chen | e464899 | 2019-11-02 17:58:54 -0700 | [diff] [blame] | 36 | ## Hardware Interfaces |
| 37 | |
Sam Elliott | d834c70 | 2020-02-12 11:18:47 +0000 | [diff] [blame] | 38 | {{< hwcfg "hw/top_earlgrey/ip/rv_plic/data/autogen/rv_plic.hjson" >}} |
Timothy Chen | e464899 | 2019-11-02 17:58:54 -0700 | [diff] [blame] | 39 | |
| 40 | ## Design Details |
lowRISC Contributors | 802543a | 2019-08-31 12:12:56 +0100 | [diff] [blame] | 41 | |
| 42 | ### Identifier |
| 43 | |
| 44 | Each interrupt source has a unique ID assigned based upon its bit position |
Greg Chadwick | 828e9d1 | 2019-10-23 11:37:24 +0100 | [diff] [blame] | 45 | within the input `intr_src_i`. ID ranges from 0 to N, the number of interrupt |
Eunchan Kim | 88a8615 | 2020-04-13 16:12:08 -0700 | [diff] [blame] | 46 | sources. ID 0 is reserved and represents no interrupt. The bit 0 of |
| 47 | `intr_src_i` shall be tied to 0 from the outside of RV_PLIC. The |
| 48 | `intr_src_i[i]` bit has an ID of `i`. This ID is used when targets "claim" the |
| 49 | interrupt and to "complete" the interrupt event. |
lowRISC Contributors | 802543a | 2019-08-31 12:12:56 +0100 | [diff] [blame] | 50 | |
| 51 | ### Priority and Threshold |
| 52 | |
Greg Chadwick | 828e9d1 | 2019-10-23 11:37:24 +0100 | [diff] [blame] | 53 | Interrupt sources have configurable priority values. The maximum value of the |
| 54 | priority is configurable through the localparam `MAX_PRIO` in the rv_plic |
Garret Kelly | 9eebde0 | 2019-10-22 15:36:49 -0400 | [diff] [blame] | 55 | top-level module. For each target there is a threshold value ({{< regref "THRESHOLD0" >}} for |
Greg Chadwick | 828e9d1 | 2019-10-23 11:37:24 +0100 | [diff] [blame] | 56 | target 0). RV_PLIC notifies a target of an interrupt only if it's priority is |
| 57 | strictly greater than the target's threshold. Note this means an interrupt with |
| 58 | a priority is 0 is effectively prevented from causing an interrupt at any target |
| 59 | and a target can suppress all interrupts by setting it's threshold to the max |
| 60 | priority value. |
lowRISC Contributors | 802543a | 2019-08-31 12:12:56 +0100 | [diff] [blame] | 61 | |
| 62 | `MAX_PRIO` parameter is most area contributing option in RV_PLIC. If `MAX_PRIO` |
Timothy Chen | e464899 | 2019-11-02 17:58:54 -0700 | [diff] [blame] | 63 | is big, then finding the highest priority in Process module may consume a lot of |
lowRISC Contributors | 802543a | 2019-08-31 12:12:56 +0100 | [diff] [blame] | 64 | logic gates. |
| 65 | |
| 66 | ### Interrupt Gateways |
| 67 | |
Greg Chadwick | 828e9d1 | 2019-10-23 11:37:24 +0100 | [diff] [blame] | 68 | The Gateway observes incoming interrupt sources and converts them to a common |
| 69 | interrupt format used internally by RV_PLIC. It can be configured to detect |
| 70 | interrupts events on an edge (when the signal changes from **0** to **1**) or |
| 71 | level basis (where the signal remains at **1**). |
| 72 | |
| 73 | When the gateway detects an interrupt event it raises the interrupt pending bit |
Garret Kelly | 9eebde0 | 2019-10-22 15:36:49 -0400 | [diff] [blame] | 74 | ({{< regref "IP" >}}) for that interrupt source. When an interrupt is claimed by a target the |
Timothy Chen | e464899 | 2019-11-02 17:58:54 -0700 | [diff] [blame] | 75 | relevant bit of {{< regref "IP" >}} is cleared. A bit in {{< regref "IP" >}} will not be reasserted until the |
Greg Chadwick | 828e9d1 | 2019-10-23 11:37:24 +0100 | [diff] [blame] | 76 | target signals completion of the interrupt. Any new interrupt event between a |
Garret Kelly | 9eebde0 | 2019-10-22 15:36:49 -0400 | [diff] [blame] | 77 | bit in {{< regref "IP" >}} asserting and completing that interrupt is ignored. In particular |
Greg Chadwick | 828e9d1 | 2019-10-23 11:37:24 +0100 | [diff] [blame] | 78 | this means that for edge triggered interrupts if a new edge is seen after the |
Timothy Chen | e464899 | 2019-11-02 17:58:54 -0700 | [diff] [blame] | 79 | source's {{< regref "IP" >}} bit is asserted but before completion, that edge will be ignored |
Greg Chadwick | 828e9d1 | 2019-10-23 11:37:24 +0100 | [diff] [blame] | 80 | (counting missed edges as discussed in the RISC-V PLIC specification is not |
| 81 | supported). |
| 82 | |
| 83 | Note that there is no ability for a level triggered interrupt to be cancelled. |
Garret Kelly | 9eebde0 | 2019-10-22 15:36:49 -0400 | [diff] [blame] | 84 | If the interrupt drops after the gateway has set a bit in {{< regref "IP" >}}, the bit will |
Greg Chadwick | 828e9d1 | 2019-10-23 11:37:24 +0100 | [diff] [blame] | 85 | remain set until the interrupt is completed. The SW handler should be conscious |
| 86 | of this and check the interrupt still requires handling in the handler if this |
| 87 | behaviour is possible. |
lowRISC Contributors | 802543a | 2019-08-31 12:12:56 +0100 | [diff] [blame] | 88 | |
| 89 | ### Interrupt Enables |
| 90 | |
Garret Kelly | 9eebde0 | 2019-10-22 15:36:49 -0400 | [diff] [blame] | 91 | Each target has a set of Interrupt Enable ({{< regref "IE0" >}} for target 0) registers. Each |
| 92 | bit in the {{< regref "IE0" >}} registers controls the corresponding interrupt source. If an |
Greg Chadwick | 828e9d1 | 2019-10-23 11:37:24 +0100 | [diff] [blame] | 93 | interrupt source is disabled for a target, then interrupt events from that |
| 94 | source won't trigger an interrupt at the target. RV_PLIC doesn't have a global |
| 95 | interrupt disable feature. |
lowRISC Contributors | 802543a | 2019-08-31 12:12:56 +0100 | [diff] [blame] | 96 | |
| 97 | ### Interrupt Claims |
| 98 | |
| 99 | "Claiming" an interrupt is done by a target reading the associated |
Garret Kelly | 9eebde0 | 2019-10-22 15:36:49 -0400 | [diff] [blame] | 100 | Claim/Completion register for the target ({{< regref "CC0" >}} for target 0). The return value |
| 101 | of the {{< regref "CC0" >}} read represents the ID of the pending interrupt that has the |
Greg Chadwick | 828e9d1 | 2019-10-23 11:37:24 +0100 | [diff] [blame] | 102 | highest priority. If two or more pending interrupts have the same priority, |
| 103 | RV_PLIC chooses the one with lowest ID. Only interrupts that that are enabled |
| 104 | for the target can be claimed. The target priority threshold doesn't matter |
| 105 | (this only factors into whether an interrupt is signalled to the target) so |
Garret Kelly | 9eebde0 | 2019-10-22 15:36:49 -0400 | [diff] [blame] | 106 | lower priority interrupt IDs can be returned on a read from {{< regref "CC0" >}}. If no |
Greg Chadwick | 828e9d1 | 2019-10-23 11:37:24 +0100 | [diff] [blame] | 107 | interrupt is pending (or all pending interrupts are disabled for the target) a |
Garret Kelly | 9eebde0 | 2019-10-22 15:36:49 -0400 | [diff] [blame] | 108 | read of {{< regref "CC0" >}} returns an ID of 0. |
lowRISC Contributors | 802543a | 2019-08-31 12:12:56 +0100 | [diff] [blame] | 109 | |
| 110 | ### Interrupt Completion |
| 111 | |
Garret Kelly | 9eebde0 | 2019-10-22 15:36:49 -0400 | [diff] [blame] | 112 | After an interrupt is claimed, the relevant bit of interrupt pending ({{< regref "IP" >}}) is |
Greg Chadwick | 828e9d1 | 2019-10-23 11:37:24 +0100 | [diff] [blame] | 113 | cleared, regardless of the status of the `intr_src_i` input value. Until a |
| 114 | target "completes" the interrupt, it won't be re-asserted if a new event for the |
| 115 | interrupt occurs. A target completes the interrupt by writing the ID of the |
Garret Kelly | 9eebde0 | 2019-10-22 15:36:49 -0400 | [diff] [blame] | 116 | interrupt to the Claim/Complete register ({{< regref "CC0" >}} for target 0). The write event |
Greg Chadwick | 828e9d1 | 2019-10-23 11:37:24 +0100 | [diff] [blame] | 117 | is forwarded to the Gateway logic, which resets the interrupt status to accept a |
| 118 | new interrupt event. The assumption is that the processor has cleaned up the |
| 119 | originating interrupt event during the time between claim and complete such that |
Eunchan Kim | 88a8615 | 2020-04-13 16:12:08 -0700 | [diff] [blame] | 120 | `intr_src_i[ID]` will have de-asserted (unless a new interrupt has occurred). |
lowRISC Contributors | 802543a | 2019-08-31 12:12:56 +0100 | [diff] [blame] | 121 | |
| 122 | ~~~~wavejson |
| 123 | { signal: [ |
| 124 | { name: 'clk', wave: 'p...........' }, |
Greg Chadwick | 828e9d1 | 2019-10-23 11:37:24 +0100 | [diff] [blame] | 125 | { name: 'intr_src_i[i]', wave: '01....0.1...', node:'.a....e.f...'}, |
| 126 | { name: 'irq_o', wave: '0.1.0......1', node:'..b.d......h'}, |
lowRISC Contributors | 802543a | 2019-08-31 12:12:56 +0100 | [diff] [blame] | 127 | { name: 'irq_id_o', wave: '=.=.=......=', |
Eunchan Kim | 88a8615 | 2020-04-13 16:12:08 -0700 | [diff] [blame] | 128 | data: ["0","i","0","i"] }, |
Greg Chadwick | 828e9d1 | 2019-10-23 11:37:24 +0100 | [diff] [blame] | 129 | { name: 'claim', wave: '0..10.......', node:'...c........'}, |
| 130 | { name: 'complete', wave: '0.........10', node:'..........g.'}, |
lowRISC Contributors | 802543a | 2019-08-31 12:12:56 +0100 | [diff] [blame] | 131 | ], |
| 132 | head:{ |
| 133 | text: 'Interrupt Flow', |
| 134 | tick: 0, |
| 135 | }, |
| 136 | } |
| 137 | ~~~~ |
| 138 | |
Eunchan Kim | 88a8615 | 2020-04-13 16:12:08 -0700 | [diff] [blame] | 139 | In the example above an interrupt for source ID `i` is configured as a level |
Greg Chadwick | 828e9d1 | 2019-10-23 11:37:24 +0100 | [diff] [blame] | 140 | interrupt and is raised at a, this results in the target being notified of the |
Eunchan Kim | 88a8615 | 2020-04-13 16:12:08 -0700 | [diff] [blame] | 141 | interrupt at b. The target claims the interrupt at c (reading `i` from it's |
Greg Chadwick | 828e9d1 | 2019-10-23 11:37:24 +0100 | [diff] [blame] | 142 | Claim/Complete register) so `irq_o` deasserts though `intr_src_i[i]` remains |
| 143 | raised. The SW handles the interrupt and it drops at e. However a new interrupt |
| 144 | quickly occurs at f. As complete hasn't been signaled yet `irq_o` isn't |
Eunchan Kim | 88a8615 | 2020-04-13 16:12:08 -0700 | [diff] [blame] | 145 | asserted. At g the interrupt is completed (by writing `i` to it's |
Greg Chadwick | 828e9d1 | 2019-10-23 11:37:24 +0100 | [diff] [blame] | 146 | Claim/Complete register) so at h `irq_o` is asserted due to the new interrupt. |
lowRISC Contributors | 802543a | 2019-08-31 12:12:56 +0100 | [diff] [blame] | 147 | |
lowRISC Contributors | 802543a | 2019-08-31 12:12:56 +0100 | [diff] [blame] | 148 | |
Garret Kelly | 9eebde0 | 2019-10-22 15:36:49 -0400 | [diff] [blame] | 149 | # Programmers Guide |
lowRISC Contributors | 802543a | 2019-08-31 12:12:56 +0100 | [diff] [blame] | 150 | |
Garret Kelly | 9eebde0 | 2019-10-22 15:36:49 -0400 | [diff] [blame] | 151 | ## Initialization |
lowRISC Contributors | 802543a | 2019-08-31 12:12:56 +0100 | [diff] [blame] | 152 | |
| 153 | After reset, RV_PLIC doesn't generate any interrupts to any targets even if |
Greg Chadwick | 828e9d1 | 2019-10-23 11:37:24 +0100 | [diff] [blame] | 154 | interrupt sources are set, as all priorities and thresholds are 0 by default and |
| 155 | all ``IE`` values are 0. Software should configure the above three registers and the |
Garret Kelly | 9eebde0 | 2019-10-22 15:36:49 -0400 | [diff] [blame] | 156 | interrupt source type {{< regref "LE" >}} . |
lowRISC Contributors | 802543a | 2019-08-31 12:12:56 +0100 | [diff] [blame] | 157 | |
Garret Kelly | 9eebde0 | 2019-10-22 15:36:49 -0400 | [diff] [blame] | 158 | {{< regref "LE" >}} and {{< regref "PRIO0" >}} .. {{< regref "PRIO31" >}} registers are unique. So, only one of the targets |
lowRISC Contributors | 802543a | 2019-08-31 12:12:56 +0100 | [diff] [blame] | 159 | shall configure them. |
| 160 | |
Garret Kelly | 9eebde0 | 2019-10-22 15:36:49 -0400 | [diff] [blame] | 161 | ```c |
lowRISC Contributors | 802543a | 2019-08-31 12:12:56 +0100 | [diff] [blame] | 162 | // Pseudo-code below |
| 163 | void plic_init() { |
| 164 | // Set to level-triggered for interrupt sources |
Alex Bradbury | a78ae46 | 2020-01-03 17:24:12 +0000 | [diff] [blame] | 165 | for (int i = 0; i < ceil(N_SOURCE / 32); ++i) { |
Miguel Young de la Sota | 0240b78 | 2019-12-20 09:33:23 -0600 | [diff] [blame] | 166 | *(LE + i) = 0; |
| 167 | } |
lowRISC Contributors | 802543a | 2019-08-31 12:12:56 +0100 | [diff] [blame] | 168 | |
| 169 | // Configure priority |
Eunchan Kim | 88a8615 | 2020-04-13 16:12:08 -0700 | [diff] [blame] | 170 | // Note that PRIO0 register doesn't affect as intr_src_i[0] is tied to 0. |
Alex Bradbury | a78ae46 | 2020-01-03 17:24:12 +0000 | [diff] [blame] | 171 | for (int i = 0; i < N_SOURCE; ++i) { |
Miguel Young de la Sota | 0240b78 | 2019-12-20 09:33:23 -0600 | [diff] [blame] | 172 | *(PRIO + i) = value(i); |
| 173 | } |
lowRISC Contributors | 802543a | 2019-08-31 12:12:56 +0100 | [diff] [blame] | 174 | } |
| 175 | |
| 176 | void plic_threshold(tid, threshold) { |
Miguel Young de la Sota | 0240b78 | 2019-12-20 09:33:23 -0600 | [diff] [blame] | 177 | *(THRESHOLD + tid) = threshold; |
lowRISC Contributors | 802543a | 2019-08-31 12:12:56 +0100 | [diff] [blame] | 178 | } |
| 179 | |
| 180 | void plic_enable(tid, iid) { |
| 181 | // iid: 0-based ID |
Miguel Young de la Sota | 0240b78 | 2019-12-20 09:33:23 -0600 | [diff] [blame] | 182 | int offset = ceil(N_SOURCE / 32) * tid + (iid >> 5); |
lowRISC Contributors | 802543a | 2019-08-31 12:12:56 +0100 | [diff] [blame] | 183 | |
Miguel Young de la Sota | 0240b78 | 2019-12-20 09:33:23 -0600 | [diff] [blame] | 184 | *(IE + offset) = *(IE + offset) | (1 << (iid % 32)); |
lowRISC Contributors | 802543a | 2019-08-31 12:12:56 +0100 | [diff] [blame] | 185 | } |
Garret Kelly | 9eebde0 | 2019-10-22 15:36:49 -0400 | [diff] [blame] | 186 | ``` |
lowRISC Contributors | 802543a | 2019-08-31 12:12:56 +0100 | [diff] [blame] | 187 | |
Garret Kelly | 9eebde0 | 2019-10-22 15:36:49 -0400 | [diff] [blame] | 188 | ## Handling Interrupt Request Events |
lowRISC Contributors | 802543a | 2019-08-31 12:12:56 +0100 | [diff] [blame] | 189 | |
| 190 | If software receives an interrupt request, it is recommended to follow the steps |
Garret Kelly | 9eebde0 | 2019-10-22 15:36:49 -0400 | [diff] [blame] | 191 | shown below (assuming target 0 which uses {{< regref "CC0" >}} for claim/complete). |
lowRISC Contributors | 802543a | 2019-08-31 12:12:56 +0100 | [diff] [blame] | 192 | |
Greg Chadwick | 828e9d1 | 2019-10-23 11:37:24 +0100 | [diff] [blame] | 193 | 1. Claim the interrupts right after entering to the interrupt service routine |
Garret Kelly | 9eebde0 | 2019-10-22 15:36:49 -0400 | [diff] [blame] | 194 | by reading the {{< regref "CC0" >}} register. |
Greg Chadwick | 828e9d1 | 2019-10-23 11:37:24 +0100 | [diff] [blame] | 195 | 2. Determine which interrupt should be serviced based on the values read from |
Garret Kelly | 9eebde0 | 2019-10-22 15:36:49 -0400 | [diff] [blame] | 196 | the {{< regref "CC0" >}} register. |
Greg Chadwick | 828e9d1 | 2019-10-23 11:37:24 +0100 | [diff] [blame] | 197 | 3. Execute ISR, clearing the originating peripheral interrupt. |
Garret Kelly | 9eebde0 | 2019-10-22 15:36:49 -0400 | [diff] [blame] | 198 | 4. Write Interrupt ID to {{< regref "CC0" >}} |
lowRISC Contributors | 802543a | 2019-08-31 12:12:56 +0100 | [diff] [blame] | 199 | 5. Repeat as necessary for other pending interrupts. |
| 200 | |
| 201 | It is possible to have multiple interrupt events claimed. If software claims one |
| 202 | interrupt request, then the process module advertises any pending interrupts |
| 203 | with lower priority unless new higher priority interrupt events occur. If a |
| 204 | higher interrupt event occurs after previous interrupt is claimed, the RV_PLIC |
| 205 | IP advertises the higher priority interrupt. Software may utilize an event |
| 206 | manager inside a loop so that interrupt claiming and completion can be |
| 207 | separated. |
| 208 | |
| 209 | ~~~~c |
| 210 | void interrupt_service() { |
Miguel Young de la Sota | 0240b78 | 2019-12-20 09:33:23 -0600 | [diff] [blame] | 211 | uint32_t tid = /* ... */; |
| 212 | uint32_t iid = *(CC + tid); |
lowRISC Contributors | 802543a | 2019-08-31 12:12:56 +0100 | [diff] [blame] | 213 | if (iid == 0) { |
Miguel Young de la Sota | 0240b78 | 2019-12-20 09:33:23 -0600 | [diff] [blame] | 214 | // Interrupt is claimed by one of other targets. |
| 215 | return; |
| 216 | } |
lowRISC Contributors | 802543a | 2019-08-31 12:12:56 +0100 | [diff] [blame] | 217 | |
| 218 | do { |
Miguel Young de la Sota | 0240b78 | 2019-12-20 09:33:23 -0600 | [diff] [blame] | 219 | // Process interrupts... |
lowRISC Contributors | 802543a | 2019-08-31 12:12:56 +0100 | [diff] [blame] | 220 | // ... |
| 221 | |
Miguel Young de la Sota | 0240b78 | 2019-12-20 09:33:23 -0600 | [diff] [blame] | 222 | // Finish. |
lowRISC Contributors | 802543a | 2019-08-31 12:12:56 +0100 | [diff] [blame] | 223 | *(CC + tid) = iid; |
| 224 | iid = *(CC + tid); |
| 225 | } while (iid != 0); |
| 226 | } |
| 227 | ~~~~ |
| 228 | |
Sam Elliott | b6745d3 | 2020-04-08 21:46:28 +0100 | [diff] [blame] | 229 | ## Device Interface Functions (DIFs) |
| 230 | |
| 231 | {{< dif_listing "sw/device/lib/dif/dif_plic.h" >}} |
| 232 | |
Garret Kelly | 9eebde0 | 2019-10-22 15:36:49 -0400 | [diff] [blame] | 233 | ## Registers |
lowRISC Contributors | 802543a | 2019-08-31 12:12:56 +0100 | [diff] [blame] | 234 | |
Sam Elliott | d834c70 | 2020-02-12 11:18:47 +0000 | [diff] [blame] | 235 | The register description below matches the instance in the [Earl Grey top level |
| 236 | design]({{< relref "hw/top_earlgrey/doc" >}}). |
lowRISC Contributors | 802543a | 2019-08-31 12:12:56 +0100 | [diff] [blame] | 237 | |
Sam Elliott | d834c70 | 2020-02-12 11:18:47 +0000 | [diff] [blame] | 238 | A similar register description can be generated with `reg_rv_plic.py` script. |
| 239 | The reason another script for register generation is that RV_PLIC is |
| 240 | configurable to the number of input sources and output targets. To implement it, |
| 241 | some of the registers (see below **IE**) should be double nested in register |
| 242 | description file. As of Jan. 2019, `regtool.py` supports only one nested |
| 243 | multiple register format `multireg`. |
| 244 | |
| 245 | The RV_PLIC in the top level is generated by topgen tool so that the number of |
Timothy Chen | e464899 | 2019-11-02 17:58:54 -0700 | [diff] [blame] | 246 | interrupt sources may be different. |
lowRISC Contributors | 802543a | 2019-08-31 12:12:56 +0100 | [diff] [blame] | 247 | |
| 248 | - LE: CEILING(N_SOURCE / DW) |
| 249 | Value 1 indicates the interrupt source's behavior is edge-triggered It is |
| 250 | used in the gateways module. |
| 251 | - IE: CEILING(N_SOURCE / DW) X N_TARGET |
| 252 | Each bit enables corresponding interrupt source. Each target has IE set. |
| 253 | - PRIO: N_SOURCE |
| 254 | Universal set across all targets. Lower n bits are valid. n is determined by |
| 255 | MAX_PRIO parameter |
| 256 | - THRESHOLD: N_TARGET |
| 257 | Priority threshold per target. Only priority of the interrupt greater than |
| 258 | threshold can raise interrupt notification to the target. |
| 259 | - IP: CEILING(N_SOURCE / DW) |
| 260 | Pending bits right after the gateways. Read-only |
| 261 | - CC: N_TARGET |
| 262 | Claim by read, complete by write |
| 263 | |
Sam Elliott | d834c70 | 2020-02-12 11:18:47 +0000 | [diff] [blame] | 264 | {{< registers "hw/top_earlgrey/ip/rv_plic/data/autogen/rv_plic.hjson" >}} |