Skip to content

Commit fc89f8f

Browse files
committed
drivers: cache: Introduce xtheadcmo cache driver
Add driver for xtheadcmo caches Signed-off-by: Camille BAUD <[email protected]>
1 parent bfea9cf commit fc89f8f

File tree

5 files changed

+275
-0
lines changed

5 files changed

+275
-0
lines changed

drivers/cache/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,3 +11,4 @@ zephyr_library_sources_ifdef(CONFIG_USERSPACE cache_handlers.c)
1111
zephyr_library_sources_ifdef(CONFIG_CACHE_NRF_CACHE cache_nrf.c)
1212
zephyr_library_sources_ifdef(CONFIG_CACHE_NXP_XCACHE cache_nxp_xcache.c)
1313
zephyr_library_sources_ifdef(CONFIG_CACHE_STM32 cache_stm32.c)
14+
zephyr_library_sources_ifdef(CONFIG_CACHE_XTHEADCMO cache_xtheadcmo.c)

drivers/cache/Kconfig

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,5 +23,6 @@ source "drivers/cache/Kconfig.nrf"
2323
source "drivers/cache/Kconfig.andes"
2424
source "drivers/cache/Kconfig.nxp_xcache"
2525
source "drivers/cache/Kconfig.stm32"
26+
source "drivers/cache/Kconfig.xuantie"
2627

2728
endif # CACHE

drivers/cache/Kconfig.xuantie

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
# Copyright (c) 2025 MASSDRIVER EI <massdriver.space>
2+
# SPDX-License-Identifier: Apache-2.0
3+
4+
config CACHE_XTHEADCMO
5+
bool "Xuantie T-HEAD xtheadcmo extension cache control driver"
6+
default y
7+
select CACHE_HAS_DRIVER
8+
help
9+
This option enables the CACHE driver for xuantie cores using the xtheadcmo extension

drivers/cache/cache_xtheadcmo.c

Lines changed: 243 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,243 @@
1+
/*
2+
* Copyright (c) 2025 MASSDRIVER EI (massdriver.space)
3+
*
4+
* SPDX-License-Identifier: Apache-2.0
5+
*/
6+
7+
#include <zephyr/init.h>
8+
#include <zephyr/kernel.h>
9+
#include <zephyr/drivers/cache.h>
10+
#include <zephyr/logging/log.h>
11+
12+
#define DT_DRV_COMPAT xuantie_xtheadcmo
13+
14+
LOG_MODULE_REGISTER(cache_xtheadcmo, CONFIG_CACHE_LOG_LEVEL);
15+
16+
struct cache_config {
17+
uint32_t icache_line_size;
18+
uint32_t dcache_line_size;
19+
};
20+
21+
static struct cache_config cache_cfg = {
22+
.icache_line_size = DT_INST_PROP(0, icache_line_size),
23+
.dcache_line_size = DT_INST_PROP(0, dcache_line_size),
24+
};
25+
26+
void __weak cache_data_enable(void)
27+
{
28+
/* Platform specific */
29+
}
30+
31+
void __weak cache_data_disable(void)
32+
{
33+
/* Platform specific */
34+
}
35+
36+
void __weak cache_instr_enable(void)
37+
{
38+
/* Platform specific */
39+
}
40+
41+
void __weak cache_instr_disable(void)
42+
{
43+
/* Platform specific */
44+
}
45+
46+
int cache_data_invd_all(void)
47+
{
48+
__asm__ volatile (
49+
"fence\n"
50+
/* th.dcache.iall */
51+
".insn 0x20000B\n"
52+
"fence\n"
53+
);
54+
55+
return 0;
56+
}
57+
58+
static void cache_invalidate_dcache_line(uintptr_t address_in)
59+
{
60+
register uintptr_t address __asm__("a3") = address_in;
61+
62+
__asm__ volatile (
63+
/* th.dcache.ipa a3*/
64+
".insn 0x2A6800B\n"
65+
:
66+
: "r"(address)
67+
);
68+
}
69+
70+
int cache_data_invd_range(void *addr_in, size_t size)
71+
{
72+
uintptr_t addr = (uintptr_t)addr_in;
73+
74+
__asm__ volatile (
75+
"fence\n"
76+
);
77+
for (uintptr_t i = addr; i < addr + size; i += cache_cfg.dcache_line_size) {
78+
cache_invalidate_dcache_line(i);
79+
}
80+
__asm__ volatile (
81+
"fence\n"
82+
);
83+
84+
return 0;
85+
}
86+
87+
int cache_instr_invd_all(void)
88+
{
89+
__asm__ volatile (
90+
"fence\n"
91+
"fence.i\n"
92+
/* th.icache.iall */
93+
".insn 0x100000B\n"
94+
"fence\n"
95+
"fence.i\n"
96+
);
97+
98+
return 0;
99+
}
100+
101+
static void cache_invalidate_icache_line(uintptr_t address_in)
102+
{
103+
register uintptr_t address __asm__("a3") = address_in;
104+
105+
__asm__ volatile (
106+
/* th.icache.ipa a3*/
107+
".insn 0x386800B\n"
108+
:
109+
: "r"(address)
110+
);
111+
}
112+
113+
int cache_instr_invd_range(void *addr_in, size_t size)
114+
{
115+
uintptr_t addr = (uintptr_t)addr_in;
116+
117+
__asm__ volatile (
118+
"fence\n"
119+
"fence.i\n"
120+
);
121+
for (uintptr_t i = addr; i < addr + size; i += cache_cfg.icache_line_size) {
122+
cache_invalidate_icache_line(i);
123+
}
124+
__asm__ volatile (
125+
"fence\n"
126+
"fence.i\n"
127+
);
128+
129+
return 0;
130+
}
131+
132+
int cache_data_flush_all(void)
133+
{
134+
__asm__ volatile (
135+
"fence\n"
136+
/* th.dcache.call */
137+
".insn 0x10000B\n"
138+
"fence\n"
139+
);
140+
141+
return 0;
142+
}
143+
144+
static void cache_clean_dcache_line(uintptr_t address_in)
145+
{
146+
register uintptr_t address __asm__("a3") = address_in;
147+
148+
__asm__ volatile (
149+
/* th.dcache.cpa a3*/
150+
".insn 0x296800B\n"
151+
:
152+
: "r"(address)
153+
);
154+
}
155+
156+
int cache_data_flush_range(void *addr_in, size_t size)
157+
{
158+
uintptr_t addr = (uintptr_t)addr_in;
159+
160+
__asm__ volatile (
161+
"fence\n"
162+
);
163+
for (uintptr_t i = addr; i < addr + size; i += cache_cfg.dcache_line_size) {
164+
cache_clean_dcache_line(i);
165+
}
166+
__asm__ volatile (
167+
"fence\n"
168+
);
169+
170+
return 0;
171+
}
172+
173+
int cache_data_flush_and_invd_all(void)
174+
{
175+
__asm__ volatile (
176+
"fence\n"
177+
/* th.dcache.ciall */
178+
".insn 0x30000B\n"
179+
"fence\n"
180+
);
181+
182+
return 0;
183+
}
184+
185+
static void cache_clean_invalidate_dcache_line(uintptr_t address_in)
186+
{
187+
register uintptr_t address __asm__("a3") = address_in;
188+
189+
__asm__ volatile (
190+
/* th.dcache.cipa a3*/
191+
".insn 0x2B6800B\n"
192+
:
193+
: "r"(address)
194+
);
195+
}
196+
197+
int cache_data_flush_and_invd_range(void *addr_in, size_t size)
198+
{
199+
uintptr_t addr = (uintptr_t)addr_in;
200+
201+
__asm__ volatile (
202+
"fence\n"
203+
);
204+
for (uintptr_t i = addr; i < addr + size; i += cache_cfg.dcache_line_size) {
205+
cache_clean_invalidate_dcache_line(i);
206+
}
207+
__asm__ volatile (
208+
"fence\n"
209+
);
210+
211+
return 0;
212+
}
213+
214+
int cache_instr_flush_all(void)
215+
{
216+
return -ENOTSUP;
217+
}
218+
219+
int cache_instr_flush_and_invd_all(void)
220+
{
221+
return -ENOTSUP;
222+
}
223+
224+
int cache_instr_flush_range(void *addr, size_t size)
225+
{
226+
ARG_UNUSED(addr);
227+
ARG_UNUSED(size);
228+
229+
return -ENOTSUP;
230+
}
231+
232+
int cache_instr_flush_and_invd_range(void *addr, size_t size)
233+
{
234+
ARG_UNUSED(addr);
235+
ARG_UNUSED(size);
236+
237+
return -ENOTSUP;
238+
}
239+
240+
void __weak arch_cache_init(void)
241+
{
242+
/* Platform specific */
243+
}
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
#
2+
# Copyright (c) 2025 MASSDRIVER EI <massdriver.space>
3+
#
4+
# SPDX-License-Identifier: Apache-2.0
5+
#
6+
7+
description: Xuantie T-HEAD xtheadcmo extension cache control
8+
9+
compatible: "xuantie,xtheadcmo"
10+
11+
include: base.yaml
12+
13+
properties:
14+
dcache-line-size:
15+
type: int
16+
description: Size of data cache line in bytes
17+
default: 32
18+
icache-line-size:
19+
type: int
20+
description: Size of data cache line in bytes
21+
default: 32

0 commit comments

Comments
 (0)