Message ID | 20250503105715.16990-3-ziyao@disroot.org |
---|---|
State | New |
Headers | show |
Series | Register Zicntr in FDT when emulating is possible | expand |
On Sat, May 3, 2025 at 4:28 PM Yao Zi <ziyao@disroot.org> wrote: > > 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. > > Suggested-by: Anup Patel <anup@brainfault.org> > Signed-off-by: Yao Zi <ziyao@disroot.org> > --- > include/sbi/sbi_hart.h | 10 ++++++++++ > lib/sbi/sbi_hart.c | 35 ++++++++++++++++++++++++++++------- > 2 files changed, 38 insertions(+), 7 deletions(-) Why are the changes in lib/sbi/sbi_timer.c dropped ? Regards, Anup > > diff --git a/include/sbi/sbi_hart.h b/include/sbi/sbi_hart.h > index bce88c5..dfbe8e4 100644 > --- a/include/sbi/sbi_hart.h > +++ b/include/sbi/sbi_hart.h > @@ -93,6 +93,14 @@ struct sbi_hart_ext_data { > > extern const struct sbi_hart_ext_data sbi_hart_ext[]; > > +/** CSRs should be detected by access and trapping */ > +enum sbi_hart_csrs { > + SBI_HART_CSR_CYCLE = 0, > + SBI_HART_CSR_TIME, > + SBI_HART_CSR_INSTRET, > + SBI_HART_CSR_MAX, > +}; > + > /* > * Smepmp enforces access boundaries between M-mode and > * S/U-mode. When it is enabled, the PMPs are programmed > @@ -112,6 +120,7 @@ struct sbi_hart_features { > bool detected; > int priv_version; > unsigned long extensions[BITS_TO_LONGS(SBI_HART_EXT_MAX)]; > + unsigned long csrs[BITS_TO_LONGS(SBI_HART_CSR_MAX)]; > unsigned int pmp_count; > unsigned int pmp_addr_bits; > unsigned int pmp_log2gran; > @@ -150,6 +159,7 @@ bool sbi_hart_has_extension(struct sbi_scratch *scratch, > enum sbi_hart_extensions ext); > void sbi_hart_get_extensions_str(struct sbi_scratch *scratch, > char *extension_str, int nestr); > +bool sbi_hart_has_csr(struct sbi_scratch *scratch, enum sbi_hart_csrs csr); > > void __attribute__((noreturn)) sbi_hart_hang(void); > > diff --git a/lib/sbi/sbi_hart.c b/lib/sbi/sbi_hart.c > index fc4925b..74ccdd8 100644 > --- a/lib/sbi/sbi_hart.c > +++ b/lib/sbi/sbi_hart.c > @@ -747,6 +747,20 @@ void sbi_hart_get_extensions_str(struct sbi_scratch *scratch, > sbi_strncpy(extensions_str, "none", nestr); > } > > +/** > + * Check whether a particular CSR is present on the HART > + * > + * @param scratch pointer to the HART scratch space > + * @param csr the CSR number to check > + */ > +bool sbi_hart_has_csr(struct sbi_scratch *scratch, enum sbi_hart_csrs csr) > +{ > + struct sbi_hart_features *hfeatures = > + sbi_scratch_offset_ptr(scratch, hart_features_offset); > + > + return __test_bit(csr, hfeatures->csrs); > +} > + > static unsigned long hart_pmp_get_allowed_addr(void) > { > unsigned long val = 0; > @@ -803,7 +817,6 @@ static int hart_detect_features(struct sbi_scratch *scratch) > struct sbi_hart_features *hfeatures = > sbi_scratch_offset_ptr(scratch, hart_features_offset); > unsigned long val, oldval; > - bool has_zicntr = false; > int rc; > > /* If hart features already detected then do nothing */ > @@ -812,6 +825,7 @@ static int hart_detect_features(struct sbi_scratch *scratch) > > /* Clear hart features */ > sbi_memset(hfeatures->extensions, 0, sizeof(hfeatures->extensions)); > + sbi_memset(hfeatures->csrs, 0, sizeof(hfeatures->csrs)); > hfeatures->pmp_count = 0; > hfeatures->mhpm_mask = 0; > hfeatures->priv_version = SBI_HART_PRIV_VER_UNKNOWN; > @@ -938,9 +952,6 @@ __pmp_skip: > /* Detect if hart supports sscofpmf */ > __check_ext_csr(SBI_HART_PRIV_VER_1_11, > CSR_SCOUNTOVF, SBI_HART_EXT_SSCOFPMF); > - /* Detect if hart supports time CSR */ > - __check_ext_csr(SBI_HART_PRIV_VER_UNKNOWN, > - CSR_TIME, SBI_HART_EXT_ZICNTR); > /* Detect if hart has AIA local interrupt CSRs */ > __check_ext_csr(SBI_HART_PRIV_VER_UNKNOWN, > CSR_MTOPI, SBI_HART_EXT_SMAIA); > @@ -962,8 +973,16 @@ __pmp_skip: > > #undef __check_ext_csr > > - /* Save trap based detection of Zicntr */ > - has_zicntr = sbi_hart_has_extension(scratch, SBI_HART_EXT_ZICNTR); > +#define __check_csr_existence(__csr, __csr_id) \ > + csr_read_allowed(__csr, &trap); \ > + if (!trap.cause) \ > + __set_bit(__csr_id, hfeatures->csrs); > + > + __check_csr_existence(CSR_CYCLE, SBI_HART_CSR_CYCLE); > + __check_csr_existence(CSR_TIME, SBI_HART_CSR_TIME); > + __check_csr_existence(CSR_INSTRET, SBI_HART_CSR_INSTRET); > + > +#undef __check_csr_existence > > /* Let platform populate extensions */ > rc = sbi_platform_extensions_init(sbi_platform_thishart_ptr(), > @@ -973,7 +992,9 @@ __pmp_skip: > > /* Zicntr should only be detected using traps */ > __sbi_hart_update_extension(hfeatures, SBI_HART_EXT_ZICNTR, > - has_zicntr); > + sbi_hart_has_csr(scratch, SBI_HART_CSR_CYCLE) && > + sbi_hart_has_csr(scratch, SBI_HART_CSR_TIME) && > + sbi_hart_has_csr(scratch, SBI_HART_CSR_INSTRET)); > > /* Extensions implied by other extensions and features */ > if (hfeatures->mhpm_mask) > -- > 2.49.0 >
On Wed, May 07, 2025 at 11:53:55AM +0530, Anup Patel wrote: > On Sat, May 3, 2025 at 4:28 PM Yao Zi <ziyao@disroot.org> wrote: > > > > 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. > > > > Suggested-by: Anup Patel <anup@brainfault.org> > > Signed-off-by: Yao Zi <ziyao@disroot.org> > > --- > > include/sbi/sbi_hart.h | 10 ++++++++++ > > lib/sbi/sbi_hart.c | 35 ++++++++++++++++++++++++++++------- > > 2 files changed, 38 insertions(+), 7 deletions(-) > > Why are the changes in lib/sbi/sbi_timer.c dropped ? Oops, I just forgot about it when writing v2. sbi_timer.c should be changed to check for only timer csr with sbi_hart_has_csr(). I'll add it back as a separate patch in v4. > Regards, > Anup Thanks, Yao Zi > > > > diff --git a/include/sbi/sbi_hart.h b/include/sbi/sbi_hart.h > > index bce88c5..dfbe8e4 100644 > > --- a/include/sbi/sbi_hart.h > > +++ b/include/sbi/sbi_hart.h > > @@ -93,6 +93,14 @@ struct sbi_hart_ext_data { > > > > extern const struct sbi_hart_ext_data sbi_hart_ext[]; > > > > +/** CSRs should be detected by access and trapping */ > > +enum sbi_hart_csrs { > > + SBI_HART_CSR_CYCLE = 0, > > + SBI_HART_CSR_TIME, > > + SBI_HART_CSR_INSTRET, > > + SBI_HART_CSR_MAX, > > +}; > > + > > /* > > * Smepmp enforces access boundaries between M-mode and > > * S/U-mode. When it is enabled, the PMPs are programmed > > @@ -112,6 +120,7 @@ struct sbi_hart_features { > > bool detected; > > int priv_version; > > unsigned long extensions[BITS_TO_LONGS(SBI_HART_EXT_MAX)]; > > + unsigned long csrs[BITS_TO_LONGS(SBI_HART_CSR_MAX)]; > > unsigned int pmp_count; > > unsigned int pmp_addr_bits; > > unsigned int pmp_log2gran; > > @@ -150,6 +159,7 @@ bool sbi_hart_has_extension(struct sbi_scratch *scratch, > > enum sbi_hart_extensions ext); > > void sbi_hart_get_extensions_str(struct sbi_scratch *scratch, > > char *extension_str, int nestr); > > +bool sbi_hart_has_csr(struct sbi_scratch *scratch, enum sbi_hart_csrs csr); > > > > void __attribute__((noreturn)) sbi_hart_hang(void); > > > > diff --git a/lib/sbi/sbi_hart.c b/lib/sbi/sbi_hart.c > > index fc4925b..74ccdd8 100644 > > --- a/lib/sbi/sbi_hart.c > > +++ b/lib/sbi/sbi_hart.c > > @@ -747,6 +747,20 @@ void sbi_hart_get_extensions_str(struct sbi_scratch *scratch, > > sbi_strncpy(extensions_str, "none", nestr); > > } > > > > +/** > > + * Check whether a particular CSR is present on the HART > > + * > > + * @param scratch pointer to the HART scratch space > > + * @param csr the CSR number to check > > + */ > > +bool sbi_hart_has_csr(struct sbi_scratch *scratch, enum sbi_hart_csrs csr) > > +{ > > + struct sbi_hart_features *hfeatures = > > + sbi_scratch_offset_ptr(scratch, hart_features_offset); > > + > > + return __test_bit(csr, hfeatures->csrs); > > +} > > + > > static unsigned long hart_pmp_get_allowed_addr(void) > > { > > unsigned long val = 0; > > @@ -803,7 +817,6 @@ static int hart_detect_features(struct sbi_scratch *scratch) > > struct sbi_hart_features *hfeatures = > > sbi_scratch_offset_ptr(scratch, hart_features_offset); > > unsigned long val, oldval; > > - bool has_zicntr = false; > > int rc; > > > > /* If hart features already detected then do nothing */ > > @@ -812,6 +825,7 @@ static int hart_detect_features(struct sbi_scratch *scratch) > > > > /* Clear hart features */ > > sbi_memset(hfeatures->extensions, 0, sizeof(hfeatures->extensions)); > > + sbi_memset(hfeatures->csrs, 0, sizeof(hfeatures->csrs)); > > hfeatures->pmp_count = 0; > > hfeatures->mhpm_mask = 0; > > hfeatures->priv_version = SBI_HART_PRIV_VER_UNKNOWN; > > @@ -938,9 +952,6 @@ __pmp_skip: > > /* Detect if hart supports sscofpmf */ > > __check_ext_csr(SBI_HART_PRIV_VER_1_11, > > CSR_SCOUNTOVF, SBI_HART_EXT_SSCOFPMF); > > - /* Detect if hart supports time CSR */ > > - __check_ext_csr(SBI_HART_PRIV_VER_UNKNOWN, > > - CSR_TIME, SBI_HART_EXT_ZICNTR); > > /* Detect if hart has AIA local interrupt CSRs */ > > __check_ext_csr(SBI_HART_PRIV_VER_UNKNOWN, > > CSR_MTOPI, SBI_HART_EXT_SMAIA); > > @@ -962,8 +973,16 @@ __pmp_skip: > > > > #undef __check_ext_csr > > > > - /* Save trap based detection of Zicntr */ > > - has_zicntr = sbi_hart_has_extension(scratch, SBI_HART_EXT_ZICNTR); > > +#define __check_csr_existence(__csr, __csr_id) \ > > + csr_read_allowed(__csr, &trap); \ > > + if (!trap.cause) \ > > + __set_bit(__csr_id, hfeatures->csrs); > > + > > + __check_csr_existence(CSR_CYCLE, SBI_HART_CSR_CYCLE); > > + __check_csr_existence(CSR_TIME, SBI_HART_CSR_TIME); > > + __check_csr_existence(CSR_INSTRET, SBI_HART_CSR_INSTRET); > > + > > +#undef __check_csr_existence > > > > /* Let platform populate extensions */ > > rc = sbi_platform_extensions_init(sbi_platform_thishart_ptr(), > > @@ -973,7 +992,9 @@ __pmp_skip: > > > > /* Zicntr should only be detected using traps */ > > __sbi_hart_update_extension(hfeatures, SBI_HART_EXT_ZICNTR, > > - has_zicntr); > > + sbi_hart_has_csr(scratch, SBI_HART_CSR_CYCLE) && > > + sbi_hart_has_csr(scratch, SBI_HART_CSR_TIME) && > > + sbi_hart_has_csr(scratch, SBI_HART_CSR_INSTRET)); > > > > /* Extensions implied by other extensions and features */ > > if (hfeatures->mhpm_mask) > > -- > > 2.49.0 > > > > -- > opensbi mailing list > opensbi@lists.infradead.org > http://lists.infradead.org/mailman/listinfo/opensbi
diff --git a/include/sbi/sbi_hart.h b/include/sbi/sbi_hart.h index bce88c5..dfbe8e4 100644 --- a/include/sbi/sbi_hart.h +++ b/include/sbi/sbi_hart.h @@ -93,6 +93,14 @@ struct sbi_hart_ext_data { extern const struct sbi_hart_ext_data sbi_hart_ext[]; +/** CSRs should be detected by access and trapping */ +enum sbi_hart_csrs { + SBI_HART_CSR_CYCLE = 0, + SBI_HART_CSR_TIME, + SBI_HART_CSR_INSTRET, + SBI_HART_CSR_MAX, +}; + /* * Smepmp enforces access boundaries between M-mode and * S/U-mode. When it is enabled, the PMPs are programmed @@ -112,6 +120,7 @@ struct sbi_hart_features { bool detected; int priv_version; unsigned long extensions[BITS_TO_LONGS(SBI_HART_EXT_MAX)]; + unsigned long csrs[BITS_TO_LONGS(SBI_HART_CSR_MAX)]; unsigned int pmp_count; unsigned int pmp_addr_bits; unsigned int pmp_log2gran; @@ -150,6 +159,7 @@ bool sbi_hart_has_extension(struct sbi_scratch *scratch, enum sbi_hart_extensions ext); void sbi_hart_get_extensions_str(struct sbi_scratch *scratch, char *extension_str, int nestr); +bool sbi_hart_has_csr(struct sbi_scratch *scratch, enum sbi_hart_csrs csr); void __attribute__((noreturn)) sbi_hart_hang(void); diff --git a/lib/sbi/sbi_hart.c b/lib/sbi/sbi_hart.c index fc4925b..74ccdd8 100644 --- a/lib/sbi/sbi_hart.c +++ b/lib/sbi/sbi_hart.c @@ -747,6 +747,20 @@ void sbi_hart_get_extensions_str(struct sbi_scratch *scratch, sbi_strncpy(extensions_str, "none", nestr); } +/** + * Check whether a particular CSR is present on the HART + * + * @param scratch pointer to the HART scratch space + * @param csr the CSR number to check + */ +bool sbi_hart_has_csr(struct sbi_scratch *scratch, enum sbi_hart_csrs csr) +{ + struct sbi_hart_features *hfeatures = + sbi_scratch_offset_ptr(scratch, hart_features_offset); + + return __test_bit(csr, hfeatures->csrs); +} + static unsigned long hart_pmp_get_allowed_addr(void) { unsigned long val = 0; @@ -803,7 +817,6 @@ static int hart_detect_features(struct sbi_scratch *scratch) struct sbi_hart_features *hfeatures = sbi_scratch_offset_ptr(scratch, hart_features_offset); unsigned long val, oldval; - bool has_zicntr = false; int rc; /* If hart features already detected then do nothing */ @@ -812,6 +825,7 @@ static int hart_detect_features(struct sbi_scratch *scratch) /* Clear hart features */ sbi_memset(hfeatures->extensions, 0, sizeof(hfeatures->extensions)); + sbi_memset(hfeatures->csrs, 0, sizeof(hfeatures->csrs)); hfeatures->pmp_count = 0; hfeatures->mhpm_mask = 0; hfeatures->priv_version = SBI_HART_PRIV_VER_UNKNOWN; @@ -938,9 +952,6 @@ __pmp_skip: /* Detect if hart supports sscofpmf */ __check_ext_csr(SBI_HART_PRIV_VER_1_11, CSR_SCOUNTOVF, SBI_HART_EXT_SSCOFPMF); - /* Detect if hart supports time CSR */ - __check_ext_csr(SBI_HART_PRIV_VER_UNKNOWN, - CSR_TIME, SBI_HART_EXT_ZICNTR); /* Detect if hart has AIA local interrupt CSRs */ __check_ext_csr(SBI_HART_PRIV_VER_UNKNOWN, CSR_MTOPI, SBI_HART_EXT_SMAIA); @@ -962,8 +973,16 @@ __pmp_skip: #undef __check_ext_csr - /* Save trap based detection of Zicntr */ - has_zicntr = sbi_hart_has_extension(scratch, SBI_HART_EXT_ZICNTR); +#define __check_csr_existence(__csr, __csr_id) \ + csr_read_allowed(__csr, &trap); \ + if (!trap.cause) \ + __set_bit(__csr_id, hfeatures->csrs); + + __check_csr_existence(CSR_CYCLE, SBI_HART_CSR_CYCLE); + __check_csr_existence(CSR_TIME, SBI_HART_CSR_TIME); + __check_csr_existence(CSR_INSTRET, SBI_HART_CSR_INSTRET); + +#undef __check_csr_existence /* Let platform populate extensions */ rc = sbi_platform_extensions_init(sbi_platform_thishart_ptr(), @@ -973,7 +992,9 @@ __pmp_skip: /* Zicntr should only be detected using traps */ __sbi_hart_update_extension(hfeatures, SBI_HART_EXT_ZICNTR, - has_zicntr); + sbi_hart_has_csr(scratch, SBI_HART_CSR_CYCLE) && + sbi_hart_has_csr(scratch, SBI_HART_CSR_TIME) && + sbi_hart_has_csr(scratch, SBI_HART_CSR_INSTRET)); /* Extensions implied by other extensions and features */ if (hfeatures->mhpm_mask)
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. Suggested-by: Anup Patel <anup@brainfault.org> Signed-off-by: Yao Zi <ziyao@disroot.org> --- include/sbi/sbi_hart.h | 10 ++++++++++ lib/sbi/sbi_hart.c | 35 ++++++++++++++++++++++++++++------- 2 files changed, 38 insertions(+), 7 deletions(-)