[Request for Comments]
This patch adds support for IMSIC on RISCV architecture.
The following features are supported:
- Interrupt delivery with aplic-imsic
- Sending IPIs between HARTS without ecall
- IPIs are sent IMSIC-to-IMSIC
Whats not supported:
- MSI interrupts from devices.
This patch is based on my previous differential: https://reviews.freebsd.org/D43293
This patch is posted to get comments as it may not be eligible for commit. It would probably need riscv: Convert local interrupt controller to a newbus PIC to land.
The problem is that the APLIC gets detected and initialised before the parent IMSIC. As a work around, I register APLIC callback in a list. When IMSIC is detected and when it configures itself, it calls the APLIC's callback. The APLIC callback calls
intr_pic_add_handler
to register itself as child of IMSIC. When IMSIC interrupt is called, it checks if that MSI is bound to an APLIC IRQ, it then calls the child handler by `intr_child_irq_handler```.
About the IPI:
Currently all IPIs are sent using an SBI ecall which is expensive. IMSIC supports IPIs using MSI writes. To handle IPIs on IMSIC, a concept of IPI device is introduced. During imsic_attach, an IPI device is registered but is not marked ready. Until it's not ready IPIs are send using ecall. These are necessary for APs bring up. Once all APs are up, the SYSINT with order SECOND is called which configures IMSIC on all the CPUs. Once all the CPUs have configured their IMSICs, the IPI device is marked ready. The IPIs then on are send using MSI writes. This is a little crude. I wanted an opinion on this approach. If okay, I can refine it or take an alternative suggested route.
MSI chosen for IPI is 1 as it has the highest priority.
IPIs over IMSIC can be disabled by "aia.imsic.ipi_disabled=1" kernel parameter.