|
@@ -40,6 +40,9 @@ static unsigned long hart_features_offset;
|
|
|
static void mstatus_init(struct sbi_scratch *scratch)
|
|
|
{
|
|
|
unsigned long mstatus_val = 0;
|
|
|
+ int cidx;
|
|
|
+ unsigned int num_mhpm = sbi_hart_mhpm_count(scratch);
|
|
|
+ uint64_t mhpmevent_init_val = 0;
|
|
|
|
|
|
/* Enable FPU */
|
|
|
if (misa_extension('D') || misa_extension('F'))
|
|
@@ -68,6 +71,21 @@ static void mstatus_init(struct sbi_scratch *scratch)
|
|
|
if (sbi_hart_has_feature(scratch, SBI_HART_HAS_MCOUNTINHIBIT))
|
|
|
csr_write(CSR_MCOUNTINHIBIT, 0xFFFFFFF8);
|
|
|
|
|
|
+ /**
|
|
|
+ * The mhpmeventn[h] CSR should be initialized with interrupt disabled
|
|
|
+ * and inhibited running in M-mode during init.
|
|
|
+ * To keep it simple, only contiguous mhpmcounters are supported as a
|
|
|
+ * platform with discontiguous mhpmcounters may not make much sense.
|
|
|
+ */
|
|
|
+ mhpmevent_init_val |= (MHPMEVENT_OF | MHPMEVENT_MINH);
|
|
|
+ for (cidx = 0; cidx < num_mhpm; cidx++) {
|
|
|
+#if __riscv_xlen == 32
|
|
|
+ csr_write_num(CSR_MHPMEVENT3 + cidx, mhpmevent_init_val & 0xFFFFFFFF);
|
|
|
+ csr_write_num(CSR_MHPMEVENT3H + cidx, mhpmevent_init_val >> BITS_PER_LONG);
|
|
|
+#else
|
|
|
+ csr_write_num(CSR_MHPMEVENT3 + cidx, mhpmevent_init_val);
|
|
|
+#endif
|
|
|
+ }
|
|
|
/* Disable all interrupts */
|
|
|
csr_write(CSR_MIE, 0);
|
|
|
|