Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

risc-v clic update #66759

Merged
merged 7 commits into from
Jan 18, 2024
Merged

risc-v clic update #66759

merged 7 commits into from
Jan 18, 2024

Conversation

raffi-g
Copy link
Contributor

@raffi-g raffi-g commented Dec 21, 2023

This PR fixes the HW vectoring functionality for more current CLIC interrupt controllers.

The mechanism for hardware vectoring has changed in the CLIC spec in 2019. Before, vectoring was enabled via mode bits in mtvec. Support for this was added in fc480c9.

For more current CLICs, this does not work anymore. Changing the mode bits is reserved. Vectoring can be enabled individually in the shv bit of clicintattr[i] (if the controller supports this feature).

I added the kconfig option CONFIG_LEGACY_CLIC, s.t. we can still support the "old" method. (as discussed some time ago with @carlocaione on Discord)


Another big thing is the usage of mnxti in the interrupt handling. Currently mcause is used to figure out the interrupt number. This works, but the pending bit is not reset like this.

According to the CLIC spec, the pending bit is always reset for edge-triggered interrupts in vectored mode. But in non-vectored mode, we have to write to the mnxti register. I adjusted the interrupt handling accordingly in this case.


The rest of the commits should be minor, more or less straight forward adjustments.


I tested the changes using a longan_nano board and the gen_isr_table test.

(I also had to slightly adjust some files for the gd32vf103 controller. This is however done in my other PR #66760.)

arch/riscv/core/isr.S Outdated Show resolved Hide resolved
@raffi-g raffi-g force-pushed the riscv-clic branch 5 times, most recently from 2600fb3 to 5f250e4 Compare January 9, 2024 13:49
arch/riscv/Kconfig Outdated Show resolved Hide resolved
The irq priority has to be called for dynamic and direct irqs, too. For
direct isrs, this was missing completely, for direct irqs just for the
clic.

For dynamic irqs, I replaced the current implementation with
`z_riscv_irq_priority_set`. For the plic, this is exaclty the same.

Signed-off-by: Greter Raffael <rgreter@baumer.com>
The trig field of clicintattr is indeed in bits 2:1. However, the mask
`CLIC_INTATTR_TRIG_Msk` is only applied directly to the bitfield
`INTATTR.b.trg`. Therefore it doesn't have to be shifted additionally.

Signed-off-by: Greter Raffael <rgreter@baumer.com>
The mechanism for hardware vectoring has changed in the clic spec
(https://github.com/riscv/riscv-fast-interrupt) in 2019. Before
vectoring was enabled via `mode` bits in `mtvec`. Support for this was
added in fc480c9.

With more current clic implementations, this does not work anymore.
Changing the `mode` bits is reserved. Vectoring can be enabled
individually in the `shv` bit of `clicintattr[i]`.

Since the old mechanism is still used, I added a new Kconfig for it.

If this Kconfig is not set, we use the `shv` bit for harware vectoring.

Signed-off-by: Greter Raffael <rgreter@baumer.com>
If CONFIG_LEGACY_CLIC is disabled, i.e. we adhere to the current CLIC
spec, the mode bits of mtvec have to be 0x3. Everything else is
reserved. Therefore if CONFIG_RISCV_VECTORED_MODE is enabled, the
current implementation is correct. If CONFIG_RISCV_VECTORED_MODE is
disabled, the mode bits have to be set, too.

Signed-off-by: Greter Raffael <rgreter@baumer.com>
In a clic the mip register does not exist and software irq are triggered
in the clicintip register.

Signed-off-by: Greter Raffael <rgreter@baumer.com>
The CLIC has different software-triggerable irqs than the PLIC. I
adjusted them.

Additionally, in a clic the the irq flag 0 would mean triggering on a
positive level. To work with software-triggering, the irqs have to
trigger on a positive edge, i.e. 1.

Signed-off-by: Greter Raffael <rgreter@baumer.com>
According to the clic specification
(https://github.com/riscv/riscv-fast-interrupt), the mnxti register has
be written, in order to clear the pending bit for non-vectored
interrupts. For vectored interrupts, this is automatically done.

From the spec:
"If the pending interrupt is edge-triggered, hardware will automatically
clear the corresponding pending bit when the CSR instruction that
accesses xnxti includes a write."

I added a kconfig `RISCV_SOC_HAS_CUSTOM_IRQ_HANDLING` to allow custom
irq handling. If enabled, `__soc_handle_all_irqs` has to be implemented.

For clic, non-vectored mode, I added a `__soc_handle_all_irqs`, that
handles the pending interrupts according to the pseudo code in the spec.

Signed-off-by: Greter Raffael <rgreter@baumer.com>
@raffi-g
Copy link
Contributor Author

raffi-g commented Jan 18, 2024

@carlocaione can you take another look?

as you've requested, I've moved the hooks into a new, ECLIC-specific file (intc_nuclei_eclic.S)

@carlescufi carlescufi merged commit 08a2ca5 into zephyrproject-rtos:main Jan 18, 2024
24 checks passed
@raffi-g raffi-g deleted the riscv-clic branch January 18, 2024 10:16
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

5 participants