* [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
* 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
* [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
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 a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox