Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add Supervisor Counter Delegation prototype #1

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions include/sbi/riscv_encoding.h
Original file line number Diff line number Diff line change
Expand Up @@ -210,9 +210,11 @@
#if __riscv_xlen > 32
#define ENVCFG_STCE (_ULL(1) << 63)
#define ENVCFG_PBMTE (_ULL(1) << 62)
#define ENVCFG_HPMDE (_ULL(1) << 61)
#else
#define ENVCFGH_STCE (_UL(1) << 31)
#define ENVCFGH_PBMTE (_UL(1) << 30)
#define ENVCFGH_HPMDE (_UL(1) << 29)
#endif
#define ENVCFG_CBZE (_UL(1) << 7)
#define ENVCFG_CBCFE (_UL(1) << 6)
Expand Down
3 changes: 2 additions & 1 deletion include/sbi/sbi_hart.h
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,8 @@ enum sbi_hart_extensions {
SBI_HART_EXT_SMSTATEEN,
/** HART has Sstc extension */
SBI_HART_EXT_SSTC,

/** HART has Sscountd extension */
SBI_HART_EXT_SSCOUNTD,
/** Maximum index of Hart extension */
SBI_HART_EXT_MAX,
};
Expand Down
38 changes: 36 additions & 2 deletions lib/sbi/sbi_hart.c
Original file line number Diff line number Diff line change
Expand Up @@ -446,6 +446,9 @@ static inline char *sbi_hart_extension_id2string(int ext)
case SBI_HART_EXT_SMSTATEEN:
estr = "smstateen";
break;
case SBI_HART_EXT_SSCOUNTD:
estr = "sscdeleg";
break;
default:
break;
}
Expand Down Expand Up @@ -553,7 +556,8 @@ static int hart_detect_features(struct sbi_scratch *scratch)
struct sbi_trap_info trap = {0};
struct sbi_hart_features *hfeatures =
sbi_scratch_offset_ptr(scratch, hart_features_offset);
unsigned long val, oldval;
unsigned long val, oldval, menvcfg_val;
bool sscountd_detected = 0;
int rc;

/* If hart features already detected then do nothing */
Expand Down Expand Up @@ -660,9 +664,39 @@ static int hart_detect_features(struct sbi_scratch *scratch)
if (hfeatures->priv_version >= SBI_HART_PRIV_VER_1_12) {
/* Detect if hart supports sscofpmf */
csr_read_allowed(CSR_SCOUNTOVF, (unsigned long)&trap);
if (!trap.cause)
menvcfg_val = csr_read(CSR_MENVCFG);
if (!trap.cause) {
__sbi_hart_update_extension(hfeatures,
SBI_HART_EXT_SSCOFPMF, true);

/* Detect if hart support sscountd */
#if __riscv_xlen > 32
/*
* Set menvcfg.HPMDE == 1 for RV64 or RV128
*
* If Svpbmt extension is not available then menvcfg.menvcfg.HPMDE
* will be read-only zero.
*/
menvcfg_val |= ENVCFG_HPMDE;
csr_write(CSR_MENVCFG, menvcfg_val);
menvcfg_val = csr_read(CSR_MENVCFG);
sscountd_detected = (menvcfg_val & ENVCFG_HPMDE) != 0;
#else
/*
* Set menvcfg.ENVCFGH_HPMDE == 1 for RV32
* If Scountd extension is not available then menvcfg.ENVCFGH_HPMDE
* will be read-only zero
*/
menvcfg_val |= ENVCFGH_HPMDE;
csr_write(CSR_MENVCFGH, menvcfg_val);
menvcfg_val = csr_read(CSR_MENVCFGH);
sscountd_detected = (menvcfg_val & ENVCFGH_HPMDE) != 0;
#endif
if (sscountd_detected != 0) {
__sbi_hart_update_extension(hfeatures,
SBI_HART_EXT_SSCOUNTD, true);
}
}
}

/* Detect if hart supports time CSR */
Expand Down