Skip to content

Commit 60c3f97

Browse files
ziyao233avpatel
authored andcommitted
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 <[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 7e31dc8 commit 60c3f97

File tree

1 file changed

+32
-1
lines changed

1 file changed

+32
-1
lines changed

lib/utils/fdt/fdt_fixup.c

Lines changed: 32 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
#include <sbi/sbi_scratch.h>
1717
#include <sbi/sbi_string.h>
1818
#include <sbi/sbi_error.h>
19+
#include <sbi/sbi_timer.h>
1920
#include <sbi_utils/fdt/fdt_fixup.h>
2021
#include <sbi_utils/fdt/fdt_pmu.h>
2122
#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)
107108

108109
void fdt_cpu_fixup(void *fdt)
109110
{
111+
struct sbi_scratch *scratch = sbi_scratch_thishart_ptr();
110112
struct sbi_domain *dom = sbi_domain_thishart_ptr();
111113
int err, cpu_offset, cpus_offset, len;
112-
const char *mmu_type;
114+
const char *mmu_type, *extensions;
113115
u32 hartid, hartindex;
116+
bool emulated_zicntr;
117+
118+
/*
119+
* Claim Zicntr extension in riscv,isa-extensions if
120+
* 1. OpenSBI can emulate time CSR with a timer
121+
* 2. The other two CSRs specified by Zicntr are available
122+
*/
123+
emulated_zicntr = sbi_timer_get_device() != NULL &&
124+
sbi_hart_has_csr(scratch, SBI_HART_CSR_CYCLE) &&
125+
sbi_hart_has_csr(scratch, SBI_HART_CSR_INSTRET);
114126

115127
err = fdt_open_into(fdt, fdt, fdt_totalsize(fdt) + 32);
116128
if (err < 0)
@@ -140,6 +152,25 @@ void fdt_cpu_fixup(void *fdt)
140152
!mmu_type || !len)
141153
fdt_setprop_string(fdt, cpu_offset, "status",
142154
"disabled");
155+
156+
if (!emulated_zicntr)
157+
continue;
158+
159+
extensions = fdt_getprop(fdt, cpu_offset,
160+
"riscv,isa-extensions", &len);
161+
/*
162+
* For legacy devicetrees, don't create riscv,isa-extensions
163+
* property if there hasn't been already one.
164+
*/
165+
if (extensions &&
166+
!fdt_stringlist_contains(extensions, len, "zicntr")) {
167+
err = fdt_open_into(fdt, fdt, fdt_totalsize(fdt) + 16);
168+
if (err)
169+
continue;
170+
171+
fdt_appendprop_string(fdt, cpu_offset,
172+
"riscv,isa-extensions", "zicntr");
173+
}
143174
}
144175
}
145176

0 commit comments

Comments
 (0)