summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAtish Patra <atishp@rivosinc.com>2022-01-07 21:54:09 +0300
committerAnup Patel <anup@brainfault.org>2022-02-04 07:40:28 +0300
commita26dc609df04ca4704873b683ac03855f20b056e (patch)
tree47a5f435fc1385bd1302fb85a4f6c7fc5159d2d7
parent3b7c204dcaa58e415ad7451c2a690bb88773abbf (diff)
downloadopensbi-a26dc609df04ca4704873b683ac03855f20b056e.tar.xz
lib: sbi: Disable interrupt and inhibit counting in M-mode during init
Currently, the mhpmevent CSRs are untouched during hart init during cold/warm boot. Ideally, we should clear out all the bits except overflow and MINH bit. That is required to disable overflow interrupt and inhibit counting in M-mode to avoid any spurious interrupts before perf start. Signed-off-by: Atish Patra <atishp@rivosinc.com> Reviewed-by: Anup Patel <anup@brainfault.org>
-rw-r--r--lib/sbi/sbi_hart.c18
1 files changed, 18 insertions, 0 deletions
diff --git a/lib/sbi/sbi_hart.c b/lib/sbi/sbi_hart.c
index d9a15d9..0a65175 100644
--- a/lib/sbi/sbi_hart.c
+++ b/lib/sbi/sbi_hart.c
@@ -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);