Skip to content

Commit 7e31dc8

Browse files
ziyao233avpatel
authored andcommitted
lib: sbi: hart: Detect existence of cycle and instret CSRs for Zicntr
Zicntr extension specifies three read-only CSRs, time, cycle and instret. It isn't sufficient to report Zicntr is fully supported with only time CSR detected. This patch introduces a bitmap to sbi_hart_features to record availability of these CSRs, which are detected using traps. Zicntr is reported as present if and only if three CSRs are all available on the HARTs. Sites originally depending on SBI_HART_EXT_ZICNTR for detecting existence of time CSR are switched to detect SBI_HART_CSR_TIME instead. Suggested-by: Anup Patel <[email protected]> Signed-off-by: Yao Zi <[email protected]> Reviewed-by: Anup Patel <[email protected]> Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Anup Patel <[email protected]>
1 parent 2bb7632 commit 7e31dc8

File tree

3 files changed

+39
-8
lines changed

3 files changed

+39
-8
lines changed

include/sbi/sbi_hart.h

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -93,6 +93,14 @@ struct sbi_hart_ext_data {
9393

9494
extern const struct sbi_hart_ext_data sbi_hart_ext[];
9595

96+
/** CSRs should be detected by access and trapping */
97+
enum sbi_hart_csrs {
98+
SBI_HART_CSR_CYCLE = 0,
99+
SBI_HART_CSR_TIME,
100+
SBI_HART_CSR_INSTRET,
101+
SBI_HART_CSR_MAX,
102+
};
103+
96104
/*
97105
* Smepmp enforces access boundaries between M-mode and
98106
* S/U-mode. When it is enabled, the PMPs are programmed
@@ -112,6 +120,7 @@ struct sbi_hart_features {
112120
bool detected;
113121
int priv_version;
114122
unsigned long extensions[BITS_TO_LONGS(SBI_HART_EXT_MAX)];
123+
unsigned long csrs[BITS_TO_LONGS(SBI_HART_CSR_MAX)];
115124
unsigned int pmp_count;
116125
unsigned int pmp_addr_bits;
117126
unsigned int pmp_log2gran;
@@ -150,6 +159,7 @@ bool sbi_hart_has_extension(struct sbi_scratch *scratch,
150159
enum sbi_hart_extensions ext);
151160
void sbi_hart_get_extensions_str(struct sbi_scratch *scratch,
152161
char *extension_str, int nestr);
162+
bool sbi_hart_has_csr(struct sbi_scratch *scratch, enum sbi_hart_csrs csr);
153163

154164
void __attribute__((noreturn)) sbi_hart_hang(void);
155165

lib/sbi/sbi_hart.c

Lines changed: 28 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -747,6 +747,20 @@ void sbi_hart_get_extensions_str(struct sbi_scratch *scratch,
747747
sbi_strncpy(extensions_str, "none", nestr);
748748
}
749749

750+
/**
751+
* Check whether a particular CSR is present on the HART
752+
*
753+
* @param scratch pointer to the HART scratch space
754+
* @param csr the CSR number to check
755+
*/
756+
bool sbi_hart_has_csr(struct sbi_scratch *scratch, enum sbi_hart_csrs csr)
757+
{
758+
struct sbi_hart_features *hfeatures =
759+
sbi_scratch_offset_ptr(scratch, hart_features_offset);
760+
761+
return __test_bit(csr, hfeatures->csrs);
762+
}
763+
750764
static unsigned long hart_pmp_get_allowed_addr(void)
751765
{
752766
unsigned long val = 0;
@@ -803,7 +817,6 @@ static int hart_detect_features(struct sbi_scratch *scratch)
803817
struct sbi_hart_features *hfeatures =
804818
sbi_scratch_offset_ptr(scratch, hart_features_offset);
805819
unsigned long val, oldval;
806-
bool has_zicntr = false;
807820
int rc;
808821

809822
/* If hart features already detected then do nothing */
@@ -812,6 +825,7 @@ static int hart_detect_features(struct sbi_scratch *scratch)
812825

813826
/* Clear hart features */
814827
sbi_memset(hfeatures->extensions, 0, sizeof(hfeatures->extensions));
828+
sbi_memset(hfeatures->csrs, 0, sizeof(hfeatures->csrs));
815829
hfeatures->pmp_count = 0;
816830
hfeatures->mhpm_mask = 0;
817831
hfeatures->priv_version = SBI_HART_PRIV_VER_UNKNOWN;
@@ -938,9 +952,6 @@ static int hart_detect_features(struct sbi_scratch *scratch)
938952
/* Detect if hart supports sscofpmf */
939953
__check_ext_csr(SBI_HART_PRIV_VER_1_11,
940954
CSR_SCOUNTOVF, SBI_HART_EXT_SSCOFPMF);
941-
/* Detect if hart supports time CSR */
942-
__check_ext_csr(SBI_HART_PRIV_VER_UNKNOWN,
943-
CSR_TIME, SBI_HART_EXT_ZICNTR);
944955
/* Detect if hart has AIA local interrupt CSRs */
945956
__check_ext_csr(SBI_HART_PRIV_VER_UNKNOWN,
946957
CSR_MTOPI, SBI_HART_EXT_SMAIA);
@@ -962,8 +973,16 @@ static int hart_detect_features(struct sbi_scratch *scratch)
962973

963974
#undef __check_ext_csr
964975

965-
/* Save trap based detection of Zicntr */
966-
has_zicntr = sbi_hart_has_extension(scratch, SBI_HART_EXT_ZICNTR);
976+
#define __check_csr_existence(__csr, __csr_id) \
977+
csr_read_allowed(__csr, &trap); \
978+
if (!trap.cause) \
979+
__set_bit(__csr_id, hfeatures->csrs);
980+
981+
__check_csr_existence(CSR_CYCLE, SBI_HART_CSR_CYCLE);
982+
__check_csr_existence(CSR_TIME, SBI_HART_CSR_TIME);
983+
__check_csr_existence(CSR_INSTRET, SBI_HART_CSR_INSTRET);
984+
985+
#undef __check_csr_existence
967986

968987
/* Let platform populate extensions */
969988
rc = sbi_platform_extensions_init(sbi_platform_thishart_ptr(),
@@ -973,7 +992,9 @@ static int hart_detect_features(struct sbi_scratch *scratch)
973992

974993
/* Zicntr should only be detected using traps */
975994
__sbi_hart_update_extension(hfeatures, SBI_HART_EXT_ZICNTR,
976-
has_zicntr);
995+
sbi_hart_has_csr(scratch, SBI_HART_CSR_CYCLE) &&
996+
sbi_hart_has_csr(scratch, SBI_HART_CSR_TIME) &&
997+
sbi_hart_has_csr(scratch, SBI_HART_CSR_INSTRET));
977998

978999
/* Extensions implied by other extensions and features */
9791000
if (hfeatures->mhpm_mask)

lib/sbi/sbi_timer.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -185,7 +185,7 @@ int sbi_timer_init(struct sbi_scratch *scratch, bool cold_boot)
185185
if (!time_delta_off)
186186
return SBI_ENOMEM;
187187

188-
if (sbi_hart_has_extension(scratch, SBI_HART_EXT_ZICNTR))
188+
if (sbi_hart_has_csr(scratch, SBI_HART_CSR_TIME))
189189
get_time_val = get_ticks;
190190

191191
ret = sbi_platform_timer_init(plat);

0 commit comments

Comments
 (0)