[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