Skip to content

Commit

Permalink
lib: sbi: Add support for counter & instret privilege mode filtering
Browse files Browse the repository at this point in the history
This adds the support for ISA extension smcntrpmf.

Signed-off-by: Kaiwen Xue <[email protected]>
  • Loading branch information
KevinRSX committed Jul 12, 2023
1 parent ea6533a commit 0343e67
Show file tree
Hide file tree
Showing 5 changed files with 70 additions and 2 deletions.
4 changes: 4 additions & 0 deletions include/sbi/riscv_encoding.h
Original file line number Diff line number Diff line change
Expand Up @@ -602,6 +602,8 @@

/* Machine Counter Setup */
#define CSR_MCOUNTINHIBIT 0x320
#define CSR_MCYCLECFG 0x321
#define CSR_MINSTRETCFG 0x322
#define CSR_MHPMEVENT3 0x323
#define CSR_MHPMEVENT4 0x324
#define CSR_MHPMEVENT5 0x325
Expand Down Expand Up @@ -633,6 +635,8 @@
#define CSR_MHPMEVENT31 0x33f

/* For RV32 */
#define CSR_MCYCLECFGH 0x721
#define CSR_MINSTRETCFGH 0x722
#define CSR_MHPMEVENT3H 0x723
#define CSR_MHPMEVENT4H 0x724
#define CSR_MHPMEVENT5H 0x725
Expand Down
2 changes: 2 additions & 0 deletions include/sbi/sbi_hart.h
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,8 @@ enum sbi_hart_extensions {
SBI_HART_EXT_ZICNTR,
/** HART has Zihpm extension */
SBI_HART_EXT_ZIHPM,
/** Hart has Smcntrpmf extension */
SBI_HART_EXT_SMCNTRPMF,

/** Maximum index of Hart extension */
SBI_HART_EXT_MAX,
Expand Down
12 changes: 12 additions & 0 deletions lib/sbi/riscv_asm.c
Original file line number Diff line number Diff line change
Expand Up @@ -128,6 +128,8 @@ unsigned long csr_read_num(int csr_num)
switchcase_csr_read_8(CSR_MHPMCOUNTER8, ret)
switchcase_csr_read_16(CSR_MHPMCOUNTER16, ret)
switchcase_csr_read(CSR_MCOUNTINHIBIT, ret)
switchcase_csr_read(CSR_MCYCLECFG, ret)
switchcase_csr_read(CSR_MINSTRETCFG, ret)
switchcase_csr_read(CSR_MHPMEVENT3, ret)
switchcase_csr_read_4(CSR_MHPMEVENT4, ret)
switchcase_csr_read_8(CSR_MHPMEVENT8, ret)
Expand All @@ -139,6 +141,12 @@ unsigned long csr_read_num(int csr_num)
switchcase_csr_read_4(CSR_MHPMCOUNTER4H, ret)
switchcase_csr_read_8(CSR_MHPMCOUNTER8H, ret)
switchcase_csr_read_16(CSR_MHPMCOUNTER16H, ret)
/**
* The CSR range M[CYCLE, INSTRET]CFGH are available only if smcntrpmf
* extension is present. The caller must ensure that.
*/
switchcase_csr_read(CSR_MCYCLECFGH, ret)
switchcase_csr_read(CSR_MINSTRETCFGH, ret)
/**
* The CSR range MHPMEVENT[3-16]H are available only if sscofpmf
* extension is present. The caller must ensure that.
Expand Down Expand Up @@ -206,12 +214,16 @@ void csr_write_num(int csr_num, unsigned long val)
switchcase_csr_write_4(CSR_MHPMCOUNTER4H, val)
switchcase_csr_write_8(CSR_MHPMCOUNTER8H, val)
switchcase_csr_write_16(CSR_MHPMCOUNTER16H, val)
switchcase_csr_write(CSR_MCYCLECFGH, val)
switchcase_csr_write(CSR_MINSTRETCFGH, val)
switchcase_csr_write(CSR_MHPMEVENT3H, val)
switchcase_csr_write_4(CSR_MHPMEVENT4H, val)
switchcase_csr_write_8(CSR_MHPMEVENT8H, val)
switchcase_csr_write_16(CSR_MHPMEVENT16H, val)
#endif
switchcase_csr_write(CSR_MCOUNTINHIBIT, val)
switchcase_csr_write(CSR_MCYCLECFG, val)
switchcase_csr_write(CSR_MINSTRETCFG, val)
switchcase_csr_write(CSR_MHPMEVENT3, val)
switchcase_csr_write_4(CSR_MHPMEVENT4, val)
switchcase_csr_write_8(CSR_MHPMEVENT8, val)
Expand Down
11 changes: 11 additions & 0 deletions lib/sbi/sbi_hart.c
Original file line number Diff line number Diff line change
Expand Up @@ -456,6 +456,9 @@ static inline char *sbi_hart_extension_id2string(int ext)
case SBI_HART_EXT_ZIHPM:
estr = "zihpm";
break;
case SBI_HART_EXT_SMCNTRPMF:
estr = "smcntrpmf";
break;
default:
break;
}
Expand Down Expand Up @@ -703,6 +706,14 @@ static int hart_detect_features(struct sbi_scratch *scratch)
SBI_HART_EXT_SMSTATEEN, true);
}

/* Detect if hart supports smcntrpmf */
if (hfeatures->priv_version >= SBI_HART_PRIV_VER_1_12) {
csr_read_allowed(CSR_MCYCLECFG, (unsigned long)&trap);
if (!trap.cause)
__sbi_hart_update_extension(hfeatures,
SBI_HART_EXT_SMCNTRPMF, true);
}

/* Let platform populate extensions */
rc = sbi_platform_extensions_init(sbi_platform_thishart_ptr(),
hfeatures);
Expand Down
43 changes: 41 additions & 2 deletions lib/sbi/sbi_pmu.c
Original file line number Diff line number Diff line change
Expand Up @@ -609,6 +609,45 @@ static int pmu_update_hw_mhpmevent(struct sbi_pmu_hw_event *hw_evt, int ctr_idx,
return 0;
}

static int pmu_fixed_ctr_update_inhibit_bits(int fixed_ctr, unsigned long flags)
{
struct sbi_scratch *scratch = sbi_scratch_thishart_ptr();
uint64_t cfg_val = 0, cfg_csr_no;
#if __riscv_xlen == 32
uint64_t cfgh_csr_no;
#endif
if (!sbi_hart_has_extension(scratch, SBI_HART_EXT_SMCNTRPMF)) {
return fixed_ctr;
}

switch (fixed_ctr) {
case 0:
cfg_csr_no = CSR_MCYCLECFG;
#if __riscv_xlen == 32
cfgh_csr_no = CSR_MCYCLECFGH;
#endif
break;
case 2:
cfg_csr_no = CSR_MINSTRETCFG;
#if __riscv_xlen == 32
cfgh_csr_no = CSR_MINSTRETCFGH;
#endif
break;
default:
return SBI_EFAIL;
}

cfg_val |= MHPMEVENT_MINH;
pmu_update_inhibit_flags(flags, &cfg_val);
#if __riscv_xlen == 32
csr_write_num(cfg_csr_no, cfg_val & 0xFFFFFFFF);
csr_write_num(cfgh_csr_no, cfg_val >> BITS_PER_LONG);
#else
csr_write_num(cfg_csr_no, cfg_val);
#endif
return fixed_ctr;
}

static int pmu_ctr_find_fixed_fw(unsigned long evt_idx_code)
{
/* Non-programmables counters are enabled always. No need to do lookup */
Expand Down Expand Up @@ -641,7 +680,7 @@ static int pmu_ctr_find_hw(struct sbi_pmu_hart_state *phs,
fixed_ctr = pmu_ctr_find_fixed_fw(event_idx);
if (fixed_ctr >= 0 &&
!sbi_hart_has_extension(scratch, SBI_HART_EXT_SSCOFPMF))
return fixed_ctr;
return pmu_fixed_ctr_update_inhibit_bits(fixed_ctr, flags);

if (sbi_hart_priv_version(scratch) >= SBI_HART_PRIV_VER_1_11)
mctr_inhbt = csr_read(CSR_MCOUNTINHIBIT);
Expand Down Expand Up @@ -684,7 +723,7 @@ static int pmu_ctr_find_hw(struct sbi_pmu_hart_state *phs,
* Return the fixed counter as they are mandatory anyways.
*/
if (fixed_ctr >= 0)
return fixed_ctr;
return pmu_fixed_ctr_update_inhibit_bits(fixed_ctr, flags);
else
return SBI_EFAIL;
}
Expand Down

0 comments on commit 0343e67

Please sign in to comment.