| 1 | .. SPDX-License-Identifier: GPL-2.0-or-later |
| 2 | |
| 3 | Hexagon L2 Vectored Interrupt Controller |
| 4 | ======================================== |
| 5 | |
| 6 | |
| 7 | .. code-block:: none |
| 8 | |
| 9 | +-------------+ +----------------------+ |
| 10 | | l2vic | | hexagon core | |
| 11 | | | | | |
| 12 | IRQ in ---->| | | | |
| 13 | IRQ in ---->| VID0 -|----------------->| irq2 | |
| 14 | ... ---->| | | | | |
| 15 | IRQ in ---->| | | v | |
| 16 | | ... | | <int steering> | |
| 17 | | | | / | | \ | |
| 18 | IRQ in ---->| | | t0 t1 t2 t3 ...| |
| 19 | IRQ in ---->| VIDN -| | | |
| 20 | ... ---->| | | | |
| 21 | IRQ in ---->| | | Global SREG File | |
| 22 | | | | | |
| 23 | | State | | | |
| 24 | | [ ] <--|==================|==> [ VID ] | |
| 25 | | [ ] <--|==================|==> [ VID1 ] | |
| 26 | | | | | |
| 27 | +-------------+ +----------------------+ |
| 28 | |
| 29 | L2VIC/Core Integration |
| 30 | ---------------------- |
| 31 | |
| 32 | * hexagon core supports 8 external interrupt sources |
| 33 | * l2vic supports 1024 input interrupts mapped among 4 output interrupts |
| 34 | * l2vic has four output signals: { VID0, VID1, VID2, VID3 } |
| 35 | * l2vic device has a bank of registers per-VID that can be used to query |
| 36 | the status or assert new interrupts. |
| 37 | * Interrupts are 'steered' to threads based on { thread priority, 'EX' state, |
| 38 | thread interrupt mask, thread interrupt enable, global interrupt enable, |
| 39 | etc. }. |
| 40 | * Any hardware thread could conceivably handle any input interrupt, dependent |
| 41 | on state. |
| 42 | * The system register transfer instruction can read the VID0-VID3 values from |
| 43 | the l2vic when reading from hexagon core system registers "VID" and "VID1". |
| 44 | * When l2vic VID0 has multiple active interrupts, it pulses the VID0 output |
| 45 | IRQ and stores the IRQ number for the VID0 register field. Only after this |
| 46 | interrupt is cleared can the l2vic pulse the VID0 output IRQ again and provide |
| 47 | the next interrupt number on the VID0 register. |
| 48 | * The ``ciad`` instruction clears the l2vic input interrupt and un-disables the |
| 49 | core interrupt. If some/an l2vic VID0 interrupt is pending when this occurs, |
| 50 | the next interrupt should fire and any subsequent reads of the VID register |
| 51 | should reflect the newly raised interrupt. |
| 52 | * In QEMU, on an external interrupt or an unmasked-pending interrupt, |
| 53 | all vCPUs are triggered (has_work==true) and each will grab the IO lock |
| 54 | while considering the steering logic to determine whether they're the thread |
| 55 | that must handle the interrupt. |