[PATCH v3 6/6] lib: sbi: hart: Detect and enable Smrnmi before trap-based feature detection

Anup Patel anup at brainfault.org
Fri May 8 23:50:48 PDT 2026


On Thu, May 7, 2026 at 11:38 PM Evgeny Voevodin
<evvoevod at tenstorrent.com> wrote:
>
> The location of the RNMI/E trap vectors in the Smrnmi extension is
> implementation-defined, so platforms with vendor-specific NMI vector
> mechanisms must install the firmware's NMI entry points themselves.
>
> Add an smrnmi_handlers_init() callback to sbi_platform_operations that
> receives the firmware entry points and lets platform code install them
> at the hardware-specific vector locations. Two pointers are passed:
>
>   - _trap_rnmi_handler: the dedicated RNMI entry point that saves
>     context using the Smrnmi MN* CSRs and returns via mnret.
>   - _trap_handler: the regular M-mode trap entry since RNME is taken
>     as a regular M-mode trap with NMIE=0.
>
> When Smrnmi is present, install the platform's NMI vectors via the new
> callback, initialize MNSCRATCH with the per-hart scratch pointer, and
> set MNSTATUS.NMIE.
>
> Smrnmi-enabled platforms must register smrnmi_handlers_init; if the
> extension is detected but no callback is registered, sbi_panic() is
> called since enabling NMIs without handlers in place would route
> subsequent traps into nowhere.
>
> Signed-off-by: Evgeny Voevodin <evvoevod at tenstorrent.com>

LGTM.

Reviewed-by: Anup Patel <anup at brainfault.org>

Regards,
Anup

> ---
>  include/sbi/sbi_platform.h |  4 ++++
>  lib/sbi/sbi_hart.c         | 20 ++++++++++++++++++++
>  2 files changed, 24 insertions(+)
>
> diff --git a/include/sbi/sbi_platform.h b/include/sbi/sbi_platform.h
> index 715df499..fe382b56 100644
> --- a/include/sbi/sbi_platform.h
> +++ b/include/sbi/sbi_platform.h
> @@ -150,6 +150,10 @@ struct sbi_platform_operations {
>         /** platform specific pmp disable on current HART */
>         void (*pmp_disable)(unsigned int n);
>
> +       /** platform specific Smrnmi handlers init on current HART */
> +       void (*smrnmi_handlers_init)(void (*rnmi_handler)(void),
> +                       void (*rnme_handler)(void));
> +
>         /** platform specific Smrnmi NMI handler.
>          *  Returns SBI_SUCCESS on success, error code if NMI cannot be handled. */
>         int (*rnmi_handler)(struct sbi_trap_context *tcntx);
> diff --git a/lib/sbi/sbi_hart.c b/lib/sbi/sbi_hart.c
> index 781161e5..92c602aa 100644
> --- a/lib/sbi/sbi_hart.c
> +++ b/lib/sbi/sbi_hart.c
> @@ -532,6 +532,26 @@ static int hart_detect_features(struct sbi_scratch *scratch)
>         if (rc)
>                 return rc;
>
> +       if (sbi_hart_has_extension(scratch, SBI_HART_EXT_SMRNMI)) {
> +               const struct sbi_platform *plat = sbi_platform_thishart_ptr();
> +               const struct sbi_platform_operations *ops = sbi_platform_ops(plat);
> +               extern void _trap_rnmi_handler(void);
> +               extern void _trap_handler(void);
> +
> +               if (!ops || !ops->smrnmi_handlers_init)
> +                       sbi_panic("Smrnmi detected, but platform lacks smrnmi_handlers_init callback\n");
> +
> +               /* Reuse _trap_handler for the RNME slot since RNME is taken
> +                * as a regular M-mode trap with NMIE=0. */
> +               ops->smrnmi_handlers_init(_trap_rnmi_handler, _trap_handler);
> +
> +               /* Initialize MNSCRATCH for the RNMI handler */
> +               csr_write(CSR_MNSCRATCH, scratch);
> +
> +               /* Enable NMIs */
> +               csr_set(CSR_MNSTATUS, MNSTATUS_NMIE);
> +       }
> +
>  #define __check_hpm_csr(__csr, __mask)                                           \
>         oldval = csr_read_allowed(__csr, &trap);                          \
>         if (!trap.cause) {                                                \
> --
> 2.43.0
>



More information about the opensbi mailing list