Re: [PATCH v3 6/6] lib: sbi: hart: Detect and enable Smrnmi before trap-based feature detection
Anup Patel <[email protected]>
| Newsgroups | org.infradead.lists.opensbi |
|---|---|
| Message-ID | <CAAhSdy3Pm5ESW17pz5wZxrbB5hoTHVBz_rQWo9voa6s+gxi7Pw@mail.gmail.com> |
On Thu, May 7, 2026 at 11:38 PM Evgeny Voevodin <[email protected]> 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 <[email protected]> LGTM. Reviewed-by: Anup Patel <[email protected]> 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 > -- opensbi mailing list [email protected] http://lists.infradead.org/mailman/listinfo/opensbi