* [PATCH v3 0/2] Register Zicntr in FDT when emulating is possible
@ 2025-05-03 10:57 Yao Zi
2025-05-03 10:57 ` [PATCH v3 1/2] lib: sbi: hart: Detect existence of cycle and instret CSRs for Zicntr Yao Zi
2025-05-03 10:57 ` [PATCH v3 2/2] lib: utils: fdt: Claim Zicntr if time CSR emulation is possible Yao Zi
0 siblings, 2 replies; 5+ messages in thread
From: Yao Zi @ 2025-05-03 10:57 UTC (permalink / raw)
To: opensbi; +Cc: Yao Zi
OpenSBI is capable of emulating time CSR on HARTs without a full Zicntr
extension. Previously, we hardcoded Zicntr extension in the devicetree
for these cores, like JH7110 in mainline Linux[1]. This doesn't reflect
the hardware and may confuse pre-SBI bootloaders, like U-Boot running in
M-Mode.
To solve the issue, let's register Zicntr in FDT dynamically for cores
supporting it by SBI emulation, allowing pre-SBI stages to detect Zicntr
availability reliably with riscv,isa-extensions.
[1]: https://elixir.bootlin.com/linux/v6.14-rc3/source/arch/riscv/boot/dts/starfive/jh7110.dtsi#L61
Changed from v2
- Zicntr detection
- Introduce SBI_HART_CSR_MAX
- Make sbi_hart_features.csrs an array for flexibillity
- Link to v2: https://lore.kernel.org/all/20250418144758.2633-1-ziyao@disroot.org/
Changed from v1
- Zicntr detection
- Introduce a bitmap to sbi_hart_features instead of using pseudo-
extensions to represent availability of CSRs
- Change possibly misleading abbreviation "RO" to "read-only" in
commit message
- FDT fixup
- Don't register zicntr to (legacy) devicetrees where harts don't come
with a riscv,isa-extensions property
- Link to v1: https://lore.kernel.org/opensbi/20250225154103.5229-1-ziyao@disroot.org/
Yao Zi (2):
lib: sbi: hart: Detect existence of cycle and instret CSRs for Zicntr
lib: utils: fdt: Claim Zicntr if time CSR emulation is possible
include/sbi/sbi_hart.h | 10 ++++++++++
lib/sbi/sbi_hart.c | 35 ++++++++++++++++++++++++++++-------
lib/utils/fdt/fdt_fixup.c | 33 ++++++++++++++++++++++++++++++++-
3 files changed, 70 insertions(+), 8 deletions(-)
--
2.49.0
--
opensbi mailing list
opensbi@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/opensbi
^ permalink raw reply [flat|nested] 5+ messages in thread
* [PATCH v3 1/2] lib: sbi: hart: Detect existence of cycle and instret CSRs for Zicntr
2025-05-03 10:57 [PATCH v3 0/2] Register Zicntr in FDT when emulating is possible Yao Zi
@ 2025-05-03 10:57 ` Yao Zi
2025-05-07 6:23 ` Anup Patel
2025-05-03 10:57 ` [PATCH v3 2/2] lib: utils: fdt: Claim Zicntr if time CSR emulation is possible Yao Zi
1 sibling, 1 reply; 5+ messages in thread
From: Yao Zi @ 2025-05-03 10:57 UTC (permalink / raw)
To: opensbi; +Cc: Yao Zi, Anup Patel
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(-)
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
^ permalink raw reply related [flat|nested] 5+ messages in thread
* [PATCH v3 2/2] lib: utils: fdt: Claim Zicntr if time CSR emulation is possible
2025-05-03 10:57 [PATCH v3 0/2] Register Zicntr in FDT when emulating is possible Yao Zi
2025-05-03 10:57 ` [PATCH v3 1/2] lib: sbi: hart: Detect existence of cycle and instret CSRs for Zicntr Yao Zi
@ 2025-05-03 10:57 ` Yao Zi
1 sibling, 0 replies; 5+ messages in thread
From: Yao Zi @ 2025-05-03 10:57 UTC (permalink / raw)
To: opensbi; +Cc: Yao Zi
OpenSBI is capable of emulating time CSR through an external timer for
HARTs that don't implement a full Zicntr extension. Let's register
Zicntr extension in the FDT if CSR emulation is active.
This avoids hardcoding the extension in the devicetree, which may
confuse pre-SBI bootloaders.
Signed-off-by: Yao Zi <ziyao@disroot.org>
---
lib/utils/fdt/fdt_fixup.c | 33 ++++++++++++++++++++++++++++++++-
1 file changed, 32 insertions(+), 1 deletion(-)
diff --git a/lib/utils/fdt/fdt_fixup.c b/lib/utils/fdt/fdt_fixup.c
index e237dd0..f3fe8af 100644
--- a/lib/utils/fdt/fdt_fixup.c
+++ b/lib/utils/fdt/fdt_fixup.c
@@ -16,6 +16,7 @@
#include <sbi/sbi_scratch.h>
#include <sbi/sbi_string.h>
#include <sbi/sbi_error.h>
+#include <sbi/sbi_timer.h>
#include <sbi_utils/fdt/fdt_fixup.h>
#include <sbi_utils/fdt/fdt_pmu.h>
#include <sbi_utils/fdt/fdt_helper.h>
@@ -107,10 +108,21 @@ int fdt_add_cpu_idle_states(void *fdt, const struct sbi_cpu_idle_state *state)
void fdt_cpu_fixup(void *fdt)
{
+ struct sbi_scratch *scratch = sbi_scratch_thishart_ptr();
struct sbi_domain *dom = sbi_domain_thishart_ptr();
int err, cpu_offset, cpus_offset, len;
- const char *mmu_type;
+ const char *mmu_type, *extensions;
u32 hartid, hartindex;
+ bool emulated_zicntr;
+
+ /*
+ * Claim Zicntr extension in riscv,isa-extensions if
+ * 1. OpenSBI can emulate time CSR with a timer
+ * 2. The other two CSRs specified by Zicntr are available
+ */
+ emulated_zicntr = sbi_timer_get_device() != NULL &&
+ sbi_hart_has_csr(scratch, SBI_HART_CSR_CYCLE) &&
+ sbi_hart_has_csr(scratch, SBI_HART_CSR_INSTRET);
err = fdt_open_into(fdt, fdt, fdt_totalsize(fdt) + 32);
if (err < 0)
@@ -140,6 +152,25 @@ void fdt_cpu_fixup(void *fdt)
!mmu_type || !len)
fdt_setprop_string(fdt, cpu_offset, "status",
"disabled");
+
+ if (!emulated_zicntr)
+ continue;
+
+ extensions = fdt_getprop(fdt, cpu_offset,
+ "riscv,isa-extensions", &len);
+ /*
+ * For legacy devicetrees, don't create riscv,isa-extensions
+ * property if there hasn't been already one.
+ */
+ if (extensions &&
+ !fdt_stringlist_contains(extensions, len, "zicntr")) {
+ err = fdt_open_into(fdt, fdt, fdt_totalsize(fdt) + 16);
+ if (err)
+ continue;
+
+ fdt_appendprop_string(fdt, cpu_offset,
+ "riscv,isa-extensions", "zicntr");
+ }
}
}
--
2.49.0
--
opensbi mailing list
opensbi@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/opensbi
^ permalink raw reply related [flat|nested] 5+ messages in thread
* Re: [PATCH v3 1/2] lib: sbi: hart: Detect existence of cycle and instret CSRs for Zicntr
2025-05-03 10:57 ` [PATCH v3 1/2] lib: sbi: hart: Detect existence of cycle and instret CSRs for Zicntr Yao Zi
@ 2025-05-07 6:23 ` Anup Patel
2025-05-07 7:17 ` Yao Zi
0 siblings, 1 reply; 5+ messages in thread
From: Anup Patel @ 2025-05-07 6:23 UTC (permalink / raw)
To: Yao Zi; +Cc: opensbi
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
>
--
opensbi mailing list
opensbi@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/opensbi
^ permalink raw reply [flat|nested] 5+ messages in thread
* Re: [PATCH v3 1/2] lib: sbi: hart: Detect existence of cycle and instret CSRs for Zicntr
2025-05-07 6:23 ` Anup Patel
@ 2025-05-07 7:17 ` Yao Zi
0 siblings, 0 replies; 5+ messages in thread
From: Yao Zi @ 2025-05-07 7:17 UTC (permalink / raw)
To: Anup Patel; +Cc: opensbi
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
--
opensbi mailing list
opensbi@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/opensbi
^ permalink raw reply [flat|nested] 5+ messages in thread
end of thread, other threads:[~2025-05-07 8:16 UTC | newest]
Thread overview: 5+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2025-05-03 10:57 [PATCH v3 0/2] Register Zicntr in FDT when emulating is possible Yao Zi
2025-05-03 10:57 ` [PATCH v3 1/2] lib: sbi: hart: Detect existence of cycle and instret CSRs for Zicntr Yao Zi
2025-05-07 6:23 ` Anup Patel
2025-05-07 7:17 ` Yao Zi
2025-05-03 10:57 ` [PATCH v3 2/2] lib: utils: fdt: Claim Zicntr if time CSR emulation is possible Yao Zi
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.