[PATCH v2 3/3] lib: sbi: allow NULL smrnmi_handlers_init and report init mode at boot

Nia Su nia.su at sifive.com
Thu Sep 3 21:43:52 PDT 2026


Platforms with fixed or mtvec-based NMI vectors need no vendor
register programming, so calling sbi_panic() when smrnmi_handlers_init
is missing is too strict; an unhandled RNMI already falls back to
sbi_trap_error().

Allow a NULL smrnmi_handlers_init and report how Smrnmi was
initialized in the boot HART banner: "Platform" when
smrnmi_handlers_init programmed it, "Default" when it was left at its
fixed/mtvec vector.

Suggested-by: Evgeny Voevodin <evvoevod at tenstorrent.com>
Signed-off-by: Nylon Chen <nylon.chen at sifive.com>
Co-developed-by: Nia Su <nia.su at sifive.com>
Signed-off-by: Nia Su <nia.su at sifive.com>
---
 include/sbi/sbi_hart.h |  8 ++++++++
 lib/sbi/sbi_hart.c     | 35 +++++++++++++++++++++++++++--------
 lib/sbi/sbi_init.c     |  4 ++++
 3 files changed, 39 insertions(+), 8 deletions(-)

diff --git a/include/sbi/sbi_hart.h b/include/sbi/sbi_hart.h
index 543393bba41526017cd95596348e26eaa897850a..ddf1bcb2bd79aded24441db7304dfc0db14615ff 100644
--- a/include/sbi/sbi_hart.h
+++ b/include/sbi/sbi_hart.h
@@ -107,6 +107,13 @@ struct sbi_hart_ext_data {
 
 extern const struct sbi_hart_ext_data sbi_hart_ext[];
 
+/** Smrnmi vector initialization mode */
+enum sbi_hart_smrnmi_init_mode {
+	SBI_HART_SMRNMI_INIT_NONE,
+	SBI_HART_SMRNMI_INIT_DEFAULT,
+	SBI_HART_SMRNMI_INIT_PLATFORM,
+};
+
 /** CSRs should be detected by access and trapping */
 enum sbi_hart_csrs {
 	SBI_HART_CSR_CYCLE = 0,
@@ -152,6 +159,7 @@ bool sbi_hart_has_extension(struct sbi_scratch *scratch,
 void sbi_hart_get_extensions_str(struct sbi_scratch *scratch,
 				 char *extension_str, int nestr);
 bool sbi_hart_has_csr(struct sbi_scratch *scratch, enum sbi_hart_csrs csr);
+const char *sbi_hart_get_smrnmi_status_str(void);
 
 void __attribute__((noreturn)) sbi_hart_hang(void);
 
diff --git a/lib/sbi/sbi_hart.c b/lib/sbi/sbi_hart.c
index e34bbe27a8396fef80a3d69c0416898cae47ec88..455c32185e7d6e42527cb66dfdb0f18405ec09bd 100644
--- a/lib/sbi/sbi_hart.c
+++ b/lib/sbi/sbi_hart.c
@@ -466,6 +466,8 @@ static int hart_mhpm_get_allowed_bits(void)
 	return num_bits;
 }
 
+static enum sbi_hart_smrnmi_init_mode smrnmi_init_mode = SBI_HART_SMRNMI_INIT_NONE;
+
 static int sbi_smrnmi_hart_init(struct sbi_scratch *scratch)
 {
 	const struct sbi_platform *plat;
@@ -480,14 +482,19 @@ static int sbi_smrnmi_hart_init(struct sbi_scratch *scratch)
 	plat = sbi_platform_thishart_ptr();
 	ops  = sbi_platform_ops(plat);
 
-	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. */
-	ret = ops->smrnmi_handlers_init(_trap_rnmi_handler, _trap_handler);
-	if (ret)
-		return ret;
+	/*
+	 * Platforms with fixed or mtvec-based NMI vectors need no
+	 * vendor register programming; NULL callback is valid.
+	 */
+	if (ops && ops->smrnmi_handlers_init) {
+		ret = ops->smrnmi_handlers_init(_trap_rnmi_handler,
+						_trap_handler);
+		if (ret)
+			return ret;
+		smrnmi_init_mode = SBI_HART_SMRNMI_INIT_PLATFORM;
+	} else {
+		smrnmi_init_mode = SBI_HART_SMRNMI_INIT_DEFAULT;
+	}
 
 	/* Initialize MNSCRATCH for the RNMI handler */
 	csr_write(CSR_MNSCRATCH, scratch);
@@ -498,6 +505,18 @@ static int sbi_smrnmi_hart_init(struct sbi_scratch *scratch)
 	return 0;
 }
 
+const char *sbi_hart_get_smrnmi_status_str(void)
+{
+	switch (smrnmi_init_mode) {
+	case SBI_HART_SMRNMI_INIT_PLATFORM:
+		return "Platform";
+	case SBI_HART_SMRNMI_INIT_DEFAULT:
+		return "Default";
+	default:
+		return NULL;
+	}
+}
+
 static int hart_detect_features(struct sbi_scratch *scratch, bool cold_boot)
 {
 	struct sbi_trap_info trap = {0};
diff --git a/lib/sbi/sbi_init.c b/lib/sbi/sbi_init.c
index acd2f8b66273afe64a72bb275c978fed5cc7e7c2..60df5afe065f3eecc37a2cc59f4b91cfad1c081c 100644
--- a/lib/sbi/sbi_init.c
+++ b/lib/sbi/sbi_init.c
@@ -199,6 +199,10 @@ static void sbi_boot_print_hart(struct sbi_scratch *scratch, u32 hartid)
 	sbi_printf("Boot HART Debug Triggers    : %d triggers\n",
 		   sbi_dbtr_get_total_triggers());
 	sbi_hart_delegation_dump(scratch, "Boot HART ", "           ");
+
+	if (sbi_hart_get_smrnmi_status_str())
+		sbi_printf("Boot HART Smrnmi Init       : %s\n",
+			   sbi_hart_get_smrnmi_status_str());
 }
 
 static unsigned long coldboot_done;

-- 
2.43.7




More information about the opensbi mailing list