Skip to content

Commit 6aba505

Browse files
JiafeiPankartben
authored andcommitted
Revert "arch: arm64: cache: delete arm64_dcache_all"
In order to clean and invalidate all D-Cache, so reverts commit: 867ba17. Although no software broadcast between different CPU Cores for D-Cache maintaining operation, but the hardware bus system should make sure it is safety for all CPU Cores, because it is common for other SMP OS. Signed-off-by: Jiafei Pan <[email protected]>
1 parent b927659 commit 6aba505

File tree

1 file changed

+76
-3
lines changed

1 file changed

+76
-3
lines changed

include/zephyr/arch/arm64/cache.h

Lines changed: 76 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -139,19 +139,92 @@ static ALWAYS_INLINE int arm64_dcache_range(void *addr, size_t size, int op)
139139
return 0;
140140
}
141141

142+
/*
143+
* operation for all data cache
144+
* ops: K_CACHE_INVD: invalidate
145+
* K_CACHE_WB: clean
146+
* K_CACHE_WB_INVD: clean and invalidate
147+
*/
148+
static ALWAYS_INLINE int arm64_dcache_all(int op)
149+
{
150+
uint32_t clidr_el1, csselr_el1, ccsidr_el1;
151+
uint8_t loc, ctype, cache_level, line_size, way_pos;
152+
uint32_t max_ways, max_sets, dc_val, set, way;
153+
154+
if (op != K_CACHE_INVD && op != K_CACHE_WB && op != K_CACHE_WB_INVD) {
155+
return -ENOTSUP;
156+
}
157+
158+
/* Data barrier before start */
159+
barrier_dsync_fence_full();
160+
161+
clidr_el1 = read_clidr_el1();
162+
163+
loc = (clidr_el1 >> CLIDR_EL1_LOC_SHIFT) & CLIDR_EL1_LOC_MASK;
164+
if (!loc) {
165+
return 0;
166+
}
167+
168+
for (cache_level = 0; cache_level < loc; cache_level++) {
169+
ctype = (clidr_el1 >> CLIDR_EL1_CTYPE_SHIFT(cache_level)) & CLIDR_EL1_CTYPE_MASK;
170+
/* No data cache, continue */
171+
if (ctype < 2) {
172+
continue;
173+
}
174+
175+
/* select cache level */
176+
csselr_el1 = cache_level << 1;
177+
write_csselr_el1(csselr_el1);
178+
barrier_isync_fence_full();
179+
180+
ccsidr_el1 = read_ccsidr_el1();
181+
line_size = (ccsidr_el1 >> CCSIDR_EL1_LN_SZ_SHIFT & CCSIDR_EL1_LN_SZ_MASK) + 4;
182+
max_ways = (ccsidr_el1 >> CCSIDR_EL1_WAYS_SHIFT) & CCSIDR_EL1_WAYS_MASK;
183+
max_sets = (ccsidr_el1 >> CCSIDR_EL1_SETS_SHIFT) & CCSIDR_EL1_SETS_MASK;
184+
/* 32-log2(ways), bit position of way in DC operand */
185+
way_pos = __builtin_clz(max_ways);
186+
187+
for (set = 0; set <= max_sets; set++) {
188+
for (way = 0; way <= max_ways; way++) {
189+
/* way number, aligned to pos in DC operand */
190+
dc_val = way << way_pos;
191+
/* cache level, aligned to pos in DC operand */
192+
dc_val |= csselr_el1;
193+
/* set number, aligned to pos in DC operand */
194+
dc_val |= set << line_size;
195+
196+
if (op == K_CACHE_INVD) {
197+
dc_ops("isw", dc_val);
198+
} else if (op == K_CACHE_WB_INVD) {
199+
dc_ops("cisw", dc_val);
200+
} else if (op == K_CACHE_WB) {
201+
dc_ops("csw", dc_val);
202+
}
203+
}
204+
}
205+
}
206+
207+
/* Restore csselr_el1 to level 0 */
208+
write_csselr_el1(0);
209+
barrier_dsync_fence_full();
210+
barrier_isync_fence_full();
211+
212+
return 0;
213+
}
214+
142215
static ALWAYS_INLINE int arch_dcache_flush_all(void)
143216
{
144-
return -ENOTSUP;
217+
return arm64_dcache_all(K_CACHE_WB);
145218
}
146219

147220
static ALWAYS_INLINE int arch_dcache_invd_all(void)
148221
{
149-
return -ENOTSUP;
222+
return arm64_dcache_all(K_CACHE_INVD);
150223
}
151224

152225
static ALWAYS_INLINE int arch_dcache_flush_and_invd_all(void)
153226
{
154-
return -ENOTSUP;
227+
return arm64_dcache_all(K_CACHE_WB_INVD);
155228
}
156229

157230
static ALWAYS_INLINE int arch_dcache_flush_range(void *addr, size_t size)

0 commit comments

Comments
 (0)