This is an automated email from the ASF dual-hosted git repository. xiaoxiang781216 pushed a commit to branch master in repository https://gitbox.apache.org/repos/asf/nuttx.git
commit 6266800dc2a36da09ed06e9134705bc3311f21dc Author: Justin Hammond <[email protected]> AuthorDate: Sun Aug 16 18:01:25 2026 +0800 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 <[email protected]> --- arch/risc-v/src/eic7700x/eic7700x_irq.c | 6 ++---- arch/risc-v/src/eic7700x/eic7700x_irq_dispatch.c | 3 +-- arch/risc-v/src/eic7700x/hardware/eic7700x_plic.h | 17 +++++++++++++++++ 3 files changed, 20 insertions(+), 6 deletions(-) diff --git a/arch/risc-v/src/eic7700x/eic7700x_irq.c b/arch/risc-v/src/eic7700x/eic7700x_irq.c index 7f3f450d1a5..6d689bafc36 100644 --- a/arch/risc-v/src/eic7700x/eic7700x_irq.c +++ b/arch/risc-v/src/eic7700x/eic7700x_irq.c @@ -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)); } diff --git a/arch/risc-v/src/eic7700x/eic7700x_irq_dispatch.c b/arch/risc-v/src/eic7700x/eic7700x_irq_dispatch.c index 8cadae5a8c5..bbdd987cd21 100644 --- a/arch/risc-v/src/eic7700x/eic7700x_irq_dispatch.c +++ b/arch/risc-v/src/eic7700x/eic7700x_irq_dispatch.c @@ -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 */ diff --git a/arch/risc-v/src/eic7700x/hardware/eic7700x_plic.h b/arch/risc-v/src/eic7700x/hardware/eic7700x_plic.h index 0c9927a7bfe..2e84fe631a5 100644 --- a/arch/risc-v/src/eic7700x/hardware/eic7700x_plic.h +++ b/arch/risc-v/src/eic7700x/hardware/eic7700x_plic.h @@ -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 */
