[PATCH 3/7] firmware: Add RNMI/RNME handler infrastructure

Anup Patel apatel at ventanamicro.com
Mon Apr 27 20:40:17 PDT 2026


On Mon, Apr 27, 2026 at 11:31 PM Evgeny Voevodin
<evvoevod at tenstorrent.com> wrote:
>
> On Thu, Apr 23, 2026 at 10:54 AM Anup Patel <anup at brainfault.org> wrote:
> > I am leaning towards option #2 and as a separate series
> > the sbi_irqchip can be extended to support NMIs.
>
> Hi Anup,
>
> As I'm working on refactoring the Smrnmi series according to our
> discussion, I'd like to suggest to go with option 3. It would be
> much cleaner to introduce generic NMI support in irqchip and build
> Smrnmi on top of that, rather than shipping a temporary
> ops->rnmi_handler bridge now and refactoring it later.
>
> NMI support in irqchip doesn't need to be complicated. It could be
> as simple as this:
>
> irqchip NMI API:
>
>   typedef int (*sbi_nmi_handler_t)(struct sbi_trap_context *tcntx,
>                                    bool resumable);
>
>   int sbi_irqchip_register_nmi_handler(sbi_nmi_handler_t handler);
>   int sbi_irqchip_process_nmi(struct sbi_trap_context *tcntx,
>                               bool resumable);
>
> A single NMI handler callback not tied to any irqchip device since
> NMI is a system-level event. Platforms register their NMI handler
> during init.
>
> Two assembly entry points in fw_base.S:
>
> - _trap_nmi_handler -- for generic unresumable NMIs (uses
>   mscratch/mepc/mcause, returns via mret). This covers platforms
>   without Smrnmi that still have implementation-defined NMI vectors.

This introduces separate entry point other than _trap_handler which
what we should not be doing because there will be platforms which
use mtvec for RNMI exception traps (or UNMIs) so on such platforms
same _trap_handler will be used for regular traps/interrupts and UNMIs.

>
> - _trap_rnmi_handler -- for Smrnmi resumable NMIs (uses
>   mnscratch/mnepc/mncause, returns via mnret).
>
> Both save the context into the same sbi_trap_context structure and
> dispatch through sbi_irqchip_process_nmi().
>
> C-level dispatch in sbi_trap.c:
>
>   _trap_nmi_handler  -> sbi_trap_nmi_handler()  -> sbi_irqchip_process_nmi(tcntx, false)

Like discussed previously, this should be:
_trap_handler -> sbi_trap_handler()

>   _trap_rnmi_handler -> sbi_trap_rnmi_handler() -> sbi_irqchip_process_nmi(tcntx, true)
>
> The "resumable" flag lets the platform distinguish RNMI from UNMI
> if it needs to (for recovery or just reset), while platforms that
> don't care can just ignore it. This could be useful for vendors who
> want to share their platform code across platforms with Smrnmi and
> without.
>
> For RNME (exception while NMIE=0), we reuse _trap_handler as you
> suggested -- it's a regular M-mode trap at a different vector.
>
> The ops->smrnmi_handlers_init() callback stays -- platforms still
> need to install the assembly handlers at their implementation-defined
> vectors to handle RNMIs correctly.
>
> The series would then be structured as:
> 1. irqchip NMI registration API (could go in a separate patch set
>    if needed for clarity)
> 2. Smrnmi scratch space and macros which you already approved
> 3. Rest of the generic part of the Smrnmi patch set
>
> What do you think?

Rather than expanding this series, lets first get the basic
infrastructure in-place with just two low-level handlers
_trap_handler() and _trap_rnmi_handler(). Extending,
the irqchip framework for NMIs should be a separate
excercise.

Regards,
Anup



More information about the opensbi mailing list