@@ -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
*
@@ -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);
@@ -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;