@@ -215,6 +215,10 @@
#endif
+#define MNSTATUS_NMIE (_UL(0x8))
+#define MNSTATUS_MNPV (_UL(0x80))
+#define MNSTATUS_MNPP (_UL(0x1800))
+
#define MHPMEVENT_SSCOF_MASK _ULL(0xFF00000000000000)
#define ENVCFG_STCE (_ULL(1) << 63)
@@ -770,6 +774,12 @@
#define CSR_MSTATEEN3 0x30F
#define CSR_MSTATEEN3H 0x31F
+/* Smrnmi extension registers */
+#define CSR_MNSCRATCH 0x740
+#define CSR_MNEPC 0x741
+#define CSR_MNCAUSE 0x742
+#define CSR_MNSTATUS 0x744
+
/* Machine-Level High-Half CSRs (AIA) */
#define CSR_MIDELEGH 0x313
#define CSR_MIEH 0x314
@@ -79,6 +79,8 @@ enum sbi_hart_extensions {
SBI_HART_EXT_SMCTR,
/** HART has CTR S-mode CSRs */
SBI_HART_EXT_SSCTR,
+ /** HART has Smrnmi extension */
+ SBI_HART_EXT_SMRNMI,
/** Maximum index of Hart extension */
SBI_HART_EXT_MAX,
@@ -65,6 +65,11 @@ static void mstatus_init(struct sbi_scratch *scratch)
/* All programmable counters will start running at runtime after S-mode request */
if (sbi_hart_priv_version(scratch) >= SBI_HART_PRIV_VER_1_11)
csr_write(CSR_MCOUNTINHIBIT, 0xFFFFFFF8);
+ /* Detect Resumable Non-Maskable Interrupts
+ * If it exists we must enable it before all traps.
+ */
+ if (sbi_hart_has_extension(scratch, SBI_HART_EXT_SMRNMI))
+ csr_set(CSR_MNSTATUS, MNSTATUS_NMIE);
/**
* The mhpmeventn[h] CSR should be initialized with interrupt disabled
@@ -695,6 +700,7 @@ const struct sbi_hart_ext_data sbi_hart_ext[] = {
__SBI_HART_EXT_DATA(ssdbltrp, SBI_HART_EXT_SSDBLTRP),
__SBI_HART_EXT_DATA(smctr, SBI_HART_EXT_SMCTR),
__SBI_HART_EXT_DATA(ssctr, SBI_HART_EXT_SSCTR),
+ __SBI_HART_EXT_DATA(smrnmi, SBI_HART_EXT_SMRNMI),
};
_Static_assert(SBI_HART_EXT_MAX == array_size(sbi_hart_ext),