[PATCH 5/7] lib: sbi: hart: Detect and enable Smrnmi before trap-based feature detection
Evgeny Voevodin
evvoevod at tenstorrent.com
Tue Mar 10 11:31:53 PDT 2026
From: Evgeny Voevodin <evvoevod at tenstorrent.com>
Move platform extension detection to the beginning of hart_detect_features()
and enable NMIs early if Smrnmi extension is present. This ensures that
trap-based CSR probing and feature detection happen with NMIs properly
configured.
This ordering is critical: Smrnmi must be detected from device tree and
enabled before any trap-based feature detection, ensuring subsequent
expected traps are handled normally through MTVEC rather than through NMEVEC.
Also, Smrnmi-enabled platform MUST provide smrnmi_handlers_init callback
in order to set up NMI and trap handlers in platform defined way. If
handler is missing, we assume that handlers are not installed properly
and subsequent NMIs or traps will jump into nowhere. If handler is in
place we assume that platform has taken care of it and proceed.
Platforms which don't need handlers installed by design, might use empty
stub as callback.
Signed-off-by: Evgeny Voevodin <evvoevod at tenstorrent.com>
---
lib/sbi/sbi_hart.c | 34 ++++++++++++++++++++++++++++------
1 file changed, 28 insertions(+), 6 deletions(-)
diff --git a/lib/sbi/sbi_hart.c b/lib/sbi/sbi_hart.c
index 4aefb759..ed0f2037 100644
--- a/lib/sbi/sbi_hart.c
+++ b/lib/sbi/sbi_hart.c
@@ -522,6 +522,34 @@ static int hart_detect_features(struct sbi_scratch *scratch)
hfeatures->mhpm_mask = 0;
hfeatures->priv_version = SBI_HART_PRIV_VER_UNKNOWN;
+ /*
+ * Parse device tree extensions early, before any trap-based checks.
+ * This is needed to detect SMRNMI and enable it before CSR probes.
+ */
+ rc = sbi_platform_extensions_init(sbi_platform_thishart_ptr(),
+ hfeatures);
+ if (rc)
+ return rc;
+
+ /* Detect Resumable Non-Maskable Interrupts from device tree
+ * If it exists we must:
+ * 1. Check that platform has installed smrnmi_handlers_init callback
+ * 2. Enable NMIs before any trap-based checks to let subsequent traps be
+ * handled as normal expected traps
+ */
+ 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);
+ if (!ops || !ops->smrnmi_handlers_init)
+ sbi_panic("SMRNMI detected, but platform lacks smrnmi_handlers_init callback!\n");
+
+ /* Initialize MNSCRATCH with scratch pointer (for RNMI handler) */
+ csr_write(CSR_MNSCRATCH, scratch);
+
+ /* Smrnmi init callback exists and was called in sbi_platform_early_init() */
+ csr_set(CSR_MNSTATUS, MNSTATUS_NMIE);
+ }
+
#define __check_hpm_csr(__csr, __mask) \
oldval = csr_read_allowed(__csr, &trap); \
if (!trap.cause) { \
@@ -676,12 +704,6 @@ __pmp_skip:
#undef __check_csr_existence
- /* Let platform populate extensions */
- rc = sbi_platform_extensions_init(sbi_platform_thishart_ptr(),
- hfeatures);
- if (rc)
- return rc;
-
/* Zicntr should only be detected using traps */
__sbi_hart_update_extension(hfeatures, SBI_HART_EXT_ZICNTR,
sbi_hart_has_csr(scratch, SBI_HART_CSR_CYCLE) &&
--
2.43.0
More information about the opensbi
mailing list