mirror of
https://github.com/apache/nuttx.git
synced 2026-09-26 01:46:57 +08:00
arch/risc-v/eic7700x: Route external interrupts to CPU0's PLIC context.
External interrupts were enabled and claimed in the context of whichever hart the firmware handed over on, which is not fixed. They reset routed to wherever the boot loader left them, and an interrupt delivered to a context nobody services cannot be told from a device that never raised one. Enable and claim in CPU0's S mode context, which is hart 0's. Steering a source at another hart would mean choosing which, and NuttX has no way for a driver to say. Assisted-by: Claude:claude-opus-5 Signed-off-by: Justin Hammond <justin@dynam.ac>
This commit is contained in:
committed by
Xiang Xiao
parent
fc488eef01
commit
6266800dc2
@@ -155,8 +155,7 @@ void up_disable_irq(int irq)
|
||||
|
||||
if (0 <= extirq && extirq <= EIC7700X_PLIC_IRQS)
|
||||
{
|
||||
addr = EIC7700X_PLIC_ENABLE0 +
|
||||
(g_eic7700x_boot_hart * EIC7700X_PLIC_ENABLE_HART);
|
||||
addr = EIC7700X_PLIC_ENABLE_CPU0;
|
||||
modifyreg32(addr + (4 * (extirq / 32)),
|
||||
1 << (extirq % 32), 0);
|
||||
}
|
||||
@@ -200,8 +199,7 @@ void up_enable_irq(int irq)
|
||||
|
||||
if (0 <= extirq && extirq <= EIC7700X_PLIC_IRQS)
|
||||
{
|
||||
addr = EIC7700X_PLIC_ENABLE0 +
|
||||
(g_eic7700x_boot_hart * EIC7700X_PLIC_ENABLE_HART);
|
||||
addr = EIC7700X_PLIC_ENABLE_CPU0;
|
||||
modifyreg32(addr + (4 * (extirq / 32)),
|
||||
0, 1 << (extirq % 32));
|
||||
}
|
||||
|
||||
@@ -55,8 +55,7 @@
|
||||
void *riscv_dispatch_irq(uintptr_t vector, uintptr_t *regs)
|
||||
{
|
||||
int irq = (vector >> RV_IRQ_MASK) | (vector & 0xf);
|
||||
uintptr_t claim = EIC7700X_PLIC_CLAIM0 +
|
||||
(g_eic7700x_boot_hart * EIC7700X_PLIC_CLAIM_HART);
|
||||
uintptr_t claim = EIC7700X_PLIC_CLAIM_CPU0;
|
||||
|
||||
/* Firstly, check if the irq is machine external interrupt */
|
||||
|
||||
|
||||
@@ -52,4 +52,21 @@
|
||||
#define EIC7700X_PLIC_CLAIM0 (EIC7700X_PLIC_BASE + 0x201004)
|
||||
#define EIC7700X_PLIC_CLAIM_HART 0x2000
|
||||
|
||||
/* The context every external interrupt is delivered to.
|
||||
*
|
||||
* The PLIC gives each Hart two contexts, M mode followed by S mode, which is
|
||||
* why the strides above are twice a context: ENABLE0, THRESHOLD0 and CLAIM0
|
||||
* are Hart 0's S mode context, and one stride steps over the next Hart's M
|
||||
* mode context to reach its S mode one.
|
||||
*
|
||||
* NuttX enables a source in one context only, CPU0's, so CPU0 is the only
|
||||
* Hart that can be interrupted by it and the dispatcher claims from the same
|
||||
* context that enabled it. That is a decision, not a limit of the hardware:
|
||||
* steering a source at another Hart means choosing which, and NuttX has no
|
||||
* way for a driver to say. CPU0 is Hart 0, so these are the base addresses.
|
||||
*/
|
||||
|
||||
#define EIC7700X_PLIC_ENABLE_CPU0 (EIC7700X_PLIC_ENABLE0)
|
||||
#define EIC7700X_PLIC_CLAIM_CPU0 (EIC7700X_PLIC_CLAIM0)
|
||||
|
||||
#endif /* __ARCH_RISCV_SRC_EIC7700X_HARDWARE_EIC7700X_PLIC_H */
|
||||
|
||||
Reference in New Issue
Block a user