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

Evgeny Voevodin evvoevod at tenstorrent.com
Mon Apr 27 11:00:39 PDT 2026


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.

- _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)
  _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?

Thanks,
Evgeny



More information about the opensbi mailing list