From 60c3f97de840e6ad35494f9228fc83600d1dc5a2 Mon Sep 17 00:00:00 2001 From: Yao Zi Date: Fri, 16 May 2025 13:33:53 +0000 Subject: [PATCH] lib: utils: fdt: Claim Zicntr if time CSR emulation is possible OpenSBI is capable of emulating time CSR through an external timer for HARTs that don't implement a full Zicntr extension. Let's add 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 Reviewed-by: Anup Patel Link: https://lore.kernel.org/r/20250516133352.36617-4-ziyao@disroot.org Signed-off-by: Anup Patel --- 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 e237dd07..f3fe8af9 100644 --- a/lib/utils/fdt/fdt_fixup.c +++ b/lib/utils/fdt/fdt_fixup.c @@ -16,6 +16,7 @@ #include #include #include +#include #include #include #include @@ -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"); + } } }