Skip to content

Commit 62ebb98

Browse files
committed
arch: microblaze: Cache API implementation
Internal references: FWRIVERHD-4554 Signed-off-by: Alp Sayin <alpsayin@gmail.com>
1 parent 62e3242 commit 62ebb98

9 files changed

+326
-38
lines changed

arch/microblaze/core/cache.c

Lines changed: 325 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,325 @@
1+
/*
2+
* Copyright (c) 2023 Advanced Micro Devices, Inc. (AMD)
3+
* Copyright (c) 2023 Alp Sayin <alpsayin@gmail.com>
4+
*
5+
* SPDX-License-Identifier: Apache-2.0
6+
*/
7+
8+
9+
#include <errno.h>
10+
11+
#include <zephyr/arch/cpu.h>
12+
#include <zephyr/cache.h>
13+
#include <zephyr/kernel.h>
14+
15+
#include <microblaze/mb_interface.h>
16+
17+
#if defined(CONFIG_CACHE_MANAGEMENT) && defined(CONFIG_ARCH_CACHE)
18+
#if defined(CONFIG_DCACHE)
19+
20+
#define DCACHE_BASE DT_PROP_OR(_CPU, d_cache_base, 0)
21+
#define ICACHE_BASE DT_PROP_OR(_CPU, i_cache_base, 0)
22+
23+
#define DCACHE_SIZE DT_PROP_OR(_CPU, d_cache_size, 0)
24+
#define ICACHE_SIZE DT_PROP_OR(_CPU, i_cache_size, 0)
25+
26+
#define DCACHE_USE_WRITEBACK DT_PROP_OR(_CPU, d_cache_use_writeback, 0)
27+
28+
/**
29+
* @brief Enable the d-cache
30+
*
31+
* Enable the data cache.
32+
*/
33+
void arch_dcache_enable(void)
34+
{
35+
microblaze_enable_dcache();
36+
}
37+
38+
/**
39+
* @brief Disable the d-cache
40+
*
41+
* Disable the data cache.
42+
* It might be a good idea to flush the cache before disabling.
43+
*/
44+
void arch_dcache_disable(void)
45+
{
46+
microblaze_disable_dcache();
47+
}
48+
49+
/**
50+
* @brief Flush the d-cache
51+
*
52+
* Flush the whole data cache.
53+
*
54+
* @retval 0 If succeeded.
55+
* @retval -ENOTSUP If not supported.
56+
* @retval -errno Negative errno for other failures.
57+
*/
58+
int arch_dcache_flush_all(void)
59+
{
60+
return arch_dcache_flush_range(DCACHE_BASE, DCACHE_SIZE);
61+
}
62+
63+
/**
64+
* @brief Invalidate the d-cache
65+
*
66+
* Invalidate the whole data cache.
67+
*
68+
* @retval 0 If succeeded.
69+
* @retval -ENOTSUP If not supported.
70+
* @retval -errno Negative errno for other failures.
71+
*/
72+
int arch_dcache_invd_all(void)
73+
{
74+
return arch_dcache_invd_range(DCACHE_BASE, DCACHE_SIZE);
75+
}
76+
77+
/**
78+
* @brief Flush and Invalidate the d-cache
79+
*
80+
* Flush and Invalidate the whole data cache.
81+
*
82+
* @retval 0 If succeeded.
83+
* @retval -ENOTSUP If not supported.
84+
* @retval -errno Negative errno for other failures.
85+
*/
86+
int arch_dcache_flush_and_invd_all(void)
87+
{
88+
return arch_dcache_flush_and_invd_range(DCACHE_BASE, DCACHE_SIZE);
89+
}
90+
91+
/**
92+
* @brief Flush an address range in the d-cache
93+
*
94+
* Flush the specified address range of the data cache.
95+
*
96+
* @param addr Starting address to flush.
97+
* @param size Range size.
98+
*
99+
* @retval 0 If succeeded.
100+
* @retval -ENOTSUP If not supported.
101+
* @retval -errno Negative errno for other failures.
102+
*/
103+
int arch_dcache_flush_range(void *addr, size_t size)
104+
{
105+
/* if ! MICROBLAZE_DCACHE_USE_WRITEBACK then
106+
* CPU doesn't support flushing without invalidating.
107+
*/
108+
if (0 == DCACHE_USE_WRITEBACK)
109+
return -ENOTSUP;
110+
111+
const size_t incrementer = 4 * sys_cache_data_line_size_get();
112+
const intptr_t end_addr = (intptr_t)addr + size;
113+
/* Aligning start address */
114+
intptr_t address_iterator = (intptr_t)addr & (-incrementer);
115+
116+
/* We only need to iterate up to the cache size */
117+
while (address_iterator < end_addr) {
118+
wdc_flush(address_iterator);
119+
address_iterator += incrementer;
120+
}
121+
122+
return 0;
123+
}
124+
125+
/**
126+
* @brief Invalidate an address range in the d-cache
127+
*
128+
* Invalidate the specified address range of the data cache.
129+
*
130+
* @param addr Starting address to invalidate.
131+
* @param size Range size.
132+
*
133+
* @retval 0 If succeeded.
134+
* @retval -ENOTSUP If not supported.
135+
* @retval -errno Negative errno for other failures.
136+
*/
137+
int arch_dcache_invd_range(void *addr, size_t size)
138+
{
139+
const uint32_t incrementer = 4 * sys_cache_data_line_size_get();
140+
const size_t end_addr = (intptr_t)addr + size;
141+
142+
/* Aligning start address */
143+
intptr_t address_iterator = (intptr_t)addr & (-incrementer);
144+
145+
/* We only need to iterate up to the cache size */
146+
while (address_iterator < end_addr) {
147+
wic(address_iterator);
148+
address_iterator += incrementer;
149+
}
150+
151+
return 0;
152+
}
153+
154+
/**
155+
* @brief Flush and Invalidate an address range in the d-cache
156+
*
157+
* Flush and Invalidate the specified address range of the data cache.
158+
*
159+
* @param addr Starting address to flush and invalidate.
160+
* @param size Range size.
161+
*
162+
* @retval 0 If succeeded.
163+
* @retval -ENOTSUP If not supported.
164+
* @retval -errno Negative errno for other failures.
165+
*/
166+
int arch_dcache_flush_and_invd_range(void *addr, size_t size)
167+
{
168+
const uint32_t incrementer = 4 * sys_cache_data_line_size_get();
169+
const size_t end_addr = (intptr_t)addr + size;
170+
171+
/* Aligning start address */
172+
intptr_t address_iterator = (intptr_t)addr & (-incrementer);
173+
174+
/* We only need to iterate up to the cache size */
175+
while (address_iterator < end_addr) {
176+
wdc_clear(address_iterator);
177+
address_iterator += incrementer;
178+
}
179+
180+
return 0;
181+
}
182+
183+
#endif /* CONFIG_DCACHE */
184+
185+
#if defined(CONFIG_ICACHE)
186+
/**
187+
* @brief Enable the i-cache
188+
*
189+
* Enable the instruction cache.
190+
*/
191+
void arch_icache_enable(void)
192+
{
193+
microblaze_enable_icache();
194+
}
195+
196+
/**
197+
* @brief Disable the i-cache
198+
*
199+
* Disable the instruction cache.
200+
*/
201+
void arch_icache_disable(void)
202+
{
203+
microblaze_disable_icache();
204+
}
205+
206+
/**
207+
* @brief Flush the i-cache
208+
*
209+
* Flush the whole instruction cache.
210+
*
211+
* @retval 0 If succeeded.
212+
* @retval -ENOTSUP If not supported.
213+
* @retval -errno Negative errno for other failures.
214+
*/
215+
int arch_icache_flush_all(void)
216+
{
217+
return -ENOTSUP;
218+
}
219+
220+
/**
221+
* @brief Invalidate the i-cache
222+
*
223+
* Invalidate the whole instruction cache.
224+
*
225+
* @retval 0 If succeeded.
226+
* @retval -ENOTSUP If not supported.
227+
* @retval -errno Negative errno for other failures.
228+
*/
229+
int arch_icache_invd_all(void)
230+
{
231+
return arch_icache_invd_range(ICACHE_BASE, ICACHE_SIZE);
232+
}
233+
234+
/**
235+
* @brief Flush and Invalidate the i-cache
236+
*
237+
* Flush and Invalidate the whole instruction cache.
238+
*
239+
* @retval 0 If succeeded.
240+
* @retval -ENOTSUP If not supported.
241+
* @retval -errno Negative errno for other failures.
242+
*/
243+
int arch_icache_flush_and_invd_all(void)
244+
{
245+
return -ENOTSUP;
246+
}
247+
248+
/**
249+
* @brief Flush an address range in the i-cache
250+
*
251+
* Flush the specified address range of the instruction cache.
252+
*
253+
* @param addr Starting address to flush.
254+
* @param size Range size.
255+
*
256+
* @retval 0 If succeeded.
257+
* @retval -ENOTSUP If not supported.
258+
* @retval -errno Negative errno for other failures.
259+
*/
260+
int arch_icache_flush_range(void *addr, size_t size)
261+
{
262+
ARG_UNUSED(addr);
263+
ARG_UNUSED(size);
264+
265+
return -ENOTSUP;
266+
}
267+
268+
/**
269+
* @brief Invalidate an address range in the i-cache
270+
*
271+
* Invalidate the specified address range of the instruction cache.
272+
*
273+
* @param addr Starting address to invalidate.
274+
* @param size Range size.
275+
*
276+
* @retval 0 If succeeded.
277+
* @retval -ENOTSUP If not supported.
278+
* @retval -errno Negative errno for other failures.
279+
*/
280+
int arch_icache_invd_range(void *addr, size_t size)
281+
{
282+
int key = irq_lock();
283+
284+
arch_icache_disable();
285+
286+
const uint32_t incrementer = 4 * sys_cache_instr_line_size_get();
287+
const size_t end_addr = (intptr_t)addr + size;
288+
289+
/* Aligning start address */
290+
intptr_t address_iterator = (intptr_t)addr & (-incrementer);
291+
292+
/* We only need to iterate up to the cache size */
293+
while (address_iterator < end_addr) {
294+
wic(address_iterator);
295+
address_iterator += incrementer;
296+
}
297+
298+
arch_icache_enable();
299+
irq_unlock(key);
300+
301+
return 0;
302+
}
303+
304+
/**
305+
* @brief Flush and Invalidate an address range in the i-cache
306+
*
307+
* Flush and Invalidate the specified address range of the instruction cache.
308+
*
309+
* @param addr Starting address to flush and invalidate.
310+
* @param size Range size.
311+
*
312+
* @retval 0 If succeeded.
313+
* @retval -ENOTSUP If not supported.
314+
* @retval -errno Negative errno for other failures.
315+
*/
316+
int arch_icache_flush_and_invd_range(void *addr, size_t size)
317+
{
318+
ARG_UNUSED(addr);
319+
ARG_UNUSED(size);
320+
321+
return -ENOTSUP;
322+
}
323+
324+
#endif /* CONFIG_ICACHE */
325+
#endif /* CONFIG_CACHE_MANAGEMENT && CONFIG_ARCH_CACHE */

arch/microblaze/core/microblaze_disable_dcache.S

Lines changed: 1 addition & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -5,48 +5,21 @@
55
* SPDX-License-Identifier: Apache-2.0
66
*/
77

8-
9-
10-
118
.text
129
.globl microblaze_disable_dcache
1310
.ent microblaze_disable_dcache
1411
.balign 4
1512
microblaze_disable_dcache:
1613
#if CONFIG_MICROBLAZE_USE_MSR_INSTR == 1
17-
18-
#if CONFIG_MICROBLAZE_DCACHE_USE_WRITEBACK != 0
19-
addik r1, r1, -8
20-
swi r15, r1, 0
21-
/* microblaze_flush_dcache does not use r1*/
22-
brlid r15, microblaze_flush_dcache
23-
nop
24-
lwi r15, r1, 0
25-
addik r1, r1, 8
26-
#endif /* CONFIG_MICROBLAZE_DCACHE_USE_WRITEBACK != 0 */
2714
rtsd r15, 8
2815
msrclr r0, 0x80
29-
3016
#else /* CONFIG_MICROBLAZE_USE_MSR_INSTR == 1 */
31-
3217
addik r1, r1, -8
33-
34-
#if CONFIG_MICROBLAZE_DCACHE_USE_WRITEBACK != 0
35-
swi r15, r1, 0
36-
brlid r15, microblaze_flush_dcache
37-
nop
38-
#endif /* CONFIG_MICROBLAZE_DCACHE_USE_WRITEBACK != 0 */
3918
mfs r11, rmsr
4019
andi r11, r11, ~(0x80)
4120
mts rmsr, r11
42-
43-
#if CONFIG_MICROBLAZE_DCACHE_USE_WRITEBACK != 0
44-
lwi r15, r1, 0
45-
#endif /* CONFIG_MICROBLAZE_DCACHE_USE_WRITEBACK != 0 */
46-
4721
addik r1, r1, 8
4822
rtsd r15, 8
4923
nop
50-
5124
#endif /*CONFIG_MICROBLAZE_USE_MSR_INSTR == 1*/
52-
.end microblaze_disable_dcache
25+
.end microblaze_disable_dcache

arch/microblaze/core/microblaze_disable_exceptions.S

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,6 @@
55
* SPDX-License-Identifier: Apache-2.0
66
*/
77

8-
98
.text
109
.globl microblaze_disable_exceptions
1110
.ent microblaze_disable_exceptions

arch/microblaze/core/microblaze_disable_icache.S

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,6 @@
55
* SPDX-License-Identifier: Apache-2.0
66
*/
77

8-
98
.text
109
.globl microblaze_disable_icache
1110
.ent microblaze_disable_icache

arch/microblaze/core/microblaze_disable_interrupts.S

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,6 @@
55
* SPDX-License-Identifier: Apache-2.0
66
*/
77

8-
98
.text
109
.globl microblaze_disable_interrupts
1110
.ent microblaze_disable_interrupts

0 commit comments

Comments
 (0)