|
16 | 16 | #include <sbi/sbi_scratch.h> |
17 | 17 | #include <sbi/sbi_string.h> |
18 | 18 | #include <sbi/sbi_error.h> |
| 19 | +#include <sbi/sbi_timer.h> |
19 | 20 | #include <sbi_utils/fdt/fdt_fixup.h> |
20 | 21 | #include <sbi_utils/fdt/fdt_pmu.h> |
21 | 22 | #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) |
107 | 108 |
|
108 | 109 | void fdt_cpu_fixup(void *fdt) |
109 | 110 | { |
| 111 | + struct sbi_scratch *scratch = sbi_scratch_thishart_ptr(); |
110 | 112 | struct sbi_domain *dom = sbi_domain_thishart_ptr(); |
111 | 113 | int err, cpu_offset, cpus_offset, len; |
112 | | - const char *mmu_type; |
| 114 | + const char *mmu_type, *extensions; |
113 | 115 | 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); |
114 | 126 |
|
115 | 127 | err = fdt_open_into(fdt, fdt, fdt_totalsize(fdt) + 32); |
116 | 128 | if (err < 0) |
@@ -140,6 +152,25 @@ void fdt_cpu_fixup(void *fdt) |
140 | 152 | !mmu_type || !len) |
141 | 153 | fdt_setprop_string(fdt, cpu_offset, "status", |
142 | 154 | "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 | + } |
143 | 174 | } |
144 | 175 | } |
145 | 176 |
|
|
0 commit comments