zephyr/arch/riscv
Carlo Caione d395b7f1e8 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>
2023-06-17 07:49:16 -04:00
..
core arch/riscv: add support for detecting null pointer exception using PMP 2023-06-17 07:45:30 -04:00
include arch: riscv: add ARCH_HAS_SINGLE_THREAD_SUPPORT 2023-05-12 09:56:40 +02:00
CMakeLists.txt riscv: toolchain arguments for a 64-bit build 2019-08-09 09:11:45 -05:00
Kconfig riscv: Add CONFIG_RISCV_RESERVED_IRQ_ISR_TABLES_OFFSET 2023-06-17 07:49:16 -04:00
Kconfig.core riscv: Introduce Zicsr and Zifencei extensions 2022-08-29 16:57:18 +02:00
Kconfig.isa riscv: Introduce BitManip extensions 2022-08-29 16:57:18 +02:00