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

Nia Su nia.su at sifive.com
Tue Sep 15 22:56:45 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 only when the platform has set
SBI_PLATFORM_HAS_FIXED_SMRNMI_VECTOR to indicate it uses a fixed or
mtvec-based vector. This distinguishes platforms that intentionally
have nothing to program from ones that simply forgot to set the
callback, so the latter now fails instead of enabling NMIs and
jumping to an undefined vector on the first RNMI.

Report how Smrnmi was initialized in the boot HART banner: "Platform"
when smrnmi_handlers_init programmed it, "Default" when the flag was
set instead.

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_platform.h |  9 ++++++++-
 lib/sbi/sbi_hart.c         | 22 ++++++++++++++--------
 lib/sbi/sbi_init.c         |  9 +++++++++
 3 files changed, 31 insertions(+), 9 deletions(-)

diff --git a/include/sbi/sbi_platform.h b/include/sbi/sbi_platform.h
index 2cfb0976772dcff627b3c7c6bb8ff6488a3ac365..6848dc7242dc3da772209ade9ca70944b2f5fc14 100644
--- a/include/sbi/sbi_platform.h
+++ b/include/sbi/sbi_platform.h
@@ -62,8 +62,11 @@ enum sbi_platform_features {
 	/** Platform has fault delegation support */
 	SBI_PLATFORM_HAS_MFAULTS_DELEGATION = (1 << 1),
 
+	/** Platform uses a fixed or mtvec-based RNMI vector */
+	SBI_PLATFORM_HAS_FIXED_SMRNMI_VECTOR = (1 << 2),
+
 	/** Last index of Platform features*/
-	SBI_PLATFORM_HAS_LAST_FEATURE = SBI_PLATFORM_HAS_MFAULTS_DELEGATION,
+	SBI_PLATFORM_HAS_LAST_FEATURE = SBI_PLATFORM_HAS_FIXED_SMRNMI_VECTOR,
 };
 
 /** Default feature set for a platform */
@@ -250,6 +253,10 @@ assert_member_offset(struct sbi_platform, cbom_block_size, SBI_PLATFORM_CBOM_BLO
 #define sbi_platform_has_mfaults_delegation(__p) \
 	((__p)->features & SBI_PLATFORM_HAS_MFAULTS_DELEGATION)
 
+/** Check whether the platform uses a fixed/mtvec-based RNMI vector */
+#define sbi_platform_has_fixed_smrnmi_vector(__p) \
+	((__p)->features & SBI_PLATFORM_HAS_FIXED_SMRNMI_VECTOR)
+
 /**
  * Get the platform features in string format
  *
diff --git a/lib/sbi/sbi_hart.c b/lib/sbi/sbi_hart.c
index 34f02ece279333366370114333b95ced916b0e1c..817b93ec0b21f5103602fea42ea6c72684490192 100644
--- a/lib/sbi/sbi_hart.c
+++ b/lib/sbi/sbi_hart.c
@@ -480,14 +480,20 @@ 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;
+	if (ops && ops->smrnmi_handlers_init) {
+		/* 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;
+	} else if (!sbi_platform_has_fixed_smrnmi_vector(plat)) {
+		/*
+		 * No callback: platforms using a fixed/mtvec vector must set
+		 * SBI_PLATFORM_HAS_FIXED_SMRNMI_VECTOR.
+		 */
+		return SBI_ENOTSUPP;
+	}
 
 	/* Initialize MNSCRATCH for the RNMI handler */
 	csr_write(CSR_MNSCRATCH, scratch);
diff --git a/lib/sbi/sbi_init.c b/lib/sbi/sbi_init.c
index acd2f8b66273afe64a72bb275c978fed5cc7e7c2..64b8c777fc7ecb4cbfb453cd74fcbce87b0c725c 100644
--- a/lib/sbi/sbi_init.c
+++ b/lib/sbi/sbi_init.c
@@ -199,6 +199,15 @@ 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_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);
+
+		sbi_printf("Boot HART Smrnmi Init       : %s\n",
+			   (ops && ops->smrnmi_handlers_init) ?
+			   "Platform" : "Default");
+	}
 }
 
 static unsigned long coldboot_done;

-- 
2.43.7




More information about the opensbi mailing list