riscv: Add CONFIG_RISCV_RESERVED_IRQ_ISR_TABLES_OFFSET
Some RISCV platforms shipping a CLIC have a peculiar interrupt ID ordering / mapping. According to the "Core-Local Interrupt Controller (CLIC) RISC-V Privileged Architecture Extensions" Version 0.9-draft at paragraph 16.1 one of these ordering recommendations is "CLIC-mode interrupt-map for systems retaining interrupt ID compatible with CLINT mode" that is described how: The CLINT-mode interrupts retain their interrupt ID in CLIC mode. [...] The existing CLINT software interrupt bits are primarily intended for inter-hart interrupt signaling, and so are retained for that purpose. [...] CLIC interrupt inputs are allocated IDs beginning at interrupt ID 17. Any fast local interrupts that would have been connected at interrupt ID 16 and above should now be mapped into corresponding inputs of the CLIC. That is a very convoluted way to say that interrupts 0 to 15 are reserved for internal use and CLIC only controls interrupts reserved for platform use (16 up to n + 16, where n is the maximum number of interrupts supported). Let's now take now into consideration this situation in the DT: clic: interrupt-controller { ... }; device0: some-device { interrupt-parent = <&clic>; interrupts = <0x1>; ... }; and in the driver for device0: IRQ_CONNECT(DT_IRQN(node), ...); From the hardware prospective: (1a) device0 is using the first IRQ line of the CLIC (2a) the interrupt ID / exception code of the `MSTATUS` register associated to this IRQ is 17, because the IDs 0 to 15 are reserved From the software / Zephyr prospective: (1b) Zephyr is installing the IRQ vector into the SW ISR table (and into the IRQ vector table for DIRECT ISRs in case of CLIC vectored mode) at index 0x1. (2b) Zephyr is using the interrupt ID of the `MSTATUS` register to index into the SW ISR table (or IRQ vector table) It's now clear how (2a) and (2b) are in contrast with each other. To fix this problem we have to take into account the offset introduced by the reserved interrupts. To do so we introduce CONFIG_RISCV_RESERVED_IRQ_ISR_TABLES_OFFSET as hidden option for the platforms to set. This Kconfig option is used to shift the interrupt numbers when installing the IRQ vector into the SW ISR table and/or IRQ vector table. So for example in the previous case and using CONFIG_RISCV_RESERVED_IRQ_ISR_TABLES_OFFSET == 16, the IRQ vector associated to the device0 would be correctly installed at index 17 (16 + 1), matching what is reported by the `MSTATUS` register. CONFIG_NUM_IRQS must be increased accordingly. Signed-off-by: Carlo Caione <ccaione@baylibre.com>
This commit is contained in:
parent
fc480c9382
commit
d395b7f1e8
2 changed files with 17 additions and 2 deletions
|
@ -169,6 +169,19 @@ config GEN_ISR_TABLES
|
|||
config GEN_IRQ_VECTOR_TABLE
|
||||
default n
|
||||
|
||||
config RISCV_RESERVED_IRQ_ISR_TABLES_OFFSET
|
||||
int
|
||||
default 0
|
||||
depends on GEN_ISR_TABLES
|
||||
help
|
||||
On some RISCV platform the first interrupt vectors are primarly
|
||||
intended for inter-hart interrupt signaling and so retained for that
|
||||
purpose and not available. When this option is set, all the IRQ
|
||||
vectors are shifted by this offset value when installed into the
|
||||
software ISR table and the IRQ vector table. CONFIG_NUM_IRQS must be
|
||||
properly sized to take into account this offset. This is a hidden
|
||||
option which needs to be set per architecture and left alone.
|
||||
|
||||
config NUM_IRQS
|
||||
int
|
||||
|
||||
|
|
|
@ -39,13 +39,15 @@ extern void z_riscv_irq_priority_set(unsigned int irq,
|
|||
|
||||
#define ARCH_IRQ_CONNECT(irq_p, priority_p, isr_p, isr_param_p, flags_p) \
|
||||
{ \
|
||||
Z_ISR_DECLARE(irq_p, 0, isr_p, isr_param_p); \
|
||||
Z_ISR_DECLARE(irq_p + CONFIG_RISCV_RESERVED_IRQ_ISR_TABLES_OFFSET, \
|
||||
0, isr_p, isr_param_p); \
|
||||
z_riscv_irq_priority_set(irq_p, priority_p, flags_p); \
|
||||
}
|
||||
|
||||
#define ARCH_IRQ_DIRECT_CONNECT(irq_p, priority_p, isr_p, flags_p) \
|
||||
{ \
|
||||
Z_ISR_DECLARE(irq_p, ISR_FLAG_DIRECT, isr_p, NULL); \
|
||||
Z_ISR_DECLARE(irq_p + CONFIG_RISCV_RESERVED_IRQ_ISR_TABLES_OFFSET, \
|
||||
ISR_FLAG_DIRECT, isr_p, NULL); \
|
||||
}
|
||||
|
||||
#define ARCH_ISR_DIRECT_HEADER() arch_isr_direct_header()
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue