Skip to content

Commit 1afca03

Browse files
VynDragoncfriedt
authored andcommitted
arch: riscv: Add support for Xuantie CPUs
Adds some support for xuantie CPU, namely cache control Signed-off-by: Camille BAUD <[email protected]>
1 parent 45d4d4f commit 1afca03

File tree

7 files changed

+381
-0
lines changed

7 files changed

+381
-0
lines changed

arch/riscv/Kconfig

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -526,5 +526,6 @@ config RISCV_NO_MTVAL_ON_FP_TRAP
526526
to handle FP exceptions.
527527

528528
rsource "Kconfig.isa"
529+
rsource "core/Kconfig"
529530

530531
endmenu

arch/riscv/core/CMakeLists.txt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,3 +42,5 @@ if(CONFIG_GEN_SW_ISR_TABLE)
4242
zephyr_linker_sources(RODATA swi_tables.ld)
4343
endif()
4444
endif()
45+
46+
add_subdirectory_ifdef(CONFIG_XUANTIE xuantie)

arch/riscv/core/Kconfig

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
# RISC-V cores configuration options
2+
3+
# Copyright (c) 2025 MASSDRIVER EI (massdriver.space)
4+
# SPDX-License-Identifier: Apache-2.0
5+
6+
config XUANTIE
7+
bool
8+
help
9+
This option signifies the use of a CPU of the XuanTie RISC-V family
10+
11+
rsource "xuantie/Kconfig"
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
# SPDX-License-Identifier: Apache-2.0
2+
3+
zephyr_syscall_header(${ZEPHYR_BASE}/include/zephyr/cache.h)
4+
5+
zephyr_library()
6+
7+
zephyr_library_sources_ifdef(CONFIG_CACHE_XTHEADCMO cache_xtheadcmo.c)
8+
zephyr_library_sources_ifdef(CONFIG_CACHE_XTHEADCMO_E907 cache_xtheadcmo_e907.c)

arch/riscv/core/xuantie/Kconfig

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
# Copyright (c) 2025 MASSDRIVER EI (massdriver.space)
2+
# SPDX-License-Identifier: Apache-2.0
3+
4+
config XUANTIE_E907
5+
bool
6+
select XUANTIE
7+
select GEN_IRQ_VECTOR_TABLE
8+
select INCLUDE_RESET_VECTOR
9+
select RISCV_HAS_CLIC
10+
select RISCV_MACHINE_TIMER
11+
select RISCV_PRIVILEGED
12+
select RISCV_ISA_RV32I
13+
select RISCV_ISA_EXT_M
14+
select RISCV_ISA_EXT_A
15+
select RISCV_ISA_EXT_C
16+
select RISCV_ISA_EXT_ZICSR
17+
select RISCV_ISA_EXT_ZIFENCEI
18+
select RISCV_VECTORED_MODE
19+
20+
if XUANTIE
21+
22+
config CACHE_XTHEADCMO
23+
bool
24+
default y
25+
select CACHE_MANAGEMENT
26+
select CPU_HAS_ICACHE
27+
help
28+
This option enables cache support for XuanTie family of CPUs using the XTHeadCmo extension
29+
30+
if CACHE_XTHEADCMO
31+
32+
config DCACHE_LINE_SIZE
33+
default 32
34+
35+
config ICACHE_LINE_SIZE
36+
default 32
37+
38+
config CACHE_XTHEADCMO_E907
39+
bool
40+
default y
41+
depends on XUANTIE_E907
42+
select CPU_HAS_DCACHE
43+
help
44+
This option enables the additional XTHeadCmo cache functions for the E907 cores
45+
46+
endif # CACHE_XTHEADCMO
47+
48+
endif # XUANTIE
Lines changed: 203 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,203 @@
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/cache.h>
10+
11+
int arch_dcache_invd_all(void)
12+
{
13+
__asm__ volatile (
14+
"fence\n"
15+
/* th.dcache.iall */
16+
".insn 0x20000B\n"
17+
"fence\n"
18+
);
19+
20+
return 0;
21+
}
22+
23+
static void arch_cache_invalidate_dcache_line(uintptr_t address_in)
24+
{
25+
register uintptr_t address __asm__("a3") = address_in;
26+
27+
__asm__ volatile (
28+
/* th.dcache.ipa a3*/
29+
".insn 0x2A6800B\n"
30+
:
31+
: "r"(address)
32+
);
33+
}
34+
35+
int arch_dcache_invd_range(void *addr_in, size_t size)
36+
{
37+
uintptr_t addr = (uintptr_t)addr_in;
38+
39+
__asm__ volatile (
40+
"fence\n"
41+
);
42+
for (uintptr_t i = addr; i < addr + size; i += CONFIG_DCACHE_LINE_SIZE) {
43+
arch_cache_invalidate_dcache_line(i);
44+
}
45+
__asm__ volatile (
46+
"fence\n"
47+
);
48+
49+
return 0;
50+
}
51+
52+
int arch_icache_invd_all(void)
53+
{
54+
__asm__ volatile (
55+
"fence\n"
56+
"fence.i\n"
57+
/* th.icache.iall */
58+
".insn 0x100000B\n"
59+
"fence\n"
60+
"fence.i\n"
61+
);
62+
63+
return 0;
64+
}
65+
66+
static void arch_cache_invalidate_icache_line(uintptr_t address_in)
67+
{
68+
register uintptr_t address __asm__("a3") = address_in;
69+
70+
__asm__ volatile (
71+
/* th.icache.ipa a3*/
72+
".insn 0x386800B\n"
73+
:
74+
: "r"(address)
75+
);
76+
}
77+
78+
int arch_icache_invd_range(void *addr_in, size_t size)
79+
{
80+
uintptr_t addr = (uintptr_t)addr_in;
81+
82+
__asm__ volatile (
83+
"fence\n"
84+
"fence.i\n"
85+
);
86+
for (uintptr_t i = addr; i < addr + size; i += CONFIG_ICACHE_LINE_SIZE) {
87+
arch_cache_invalidate_icache_line(i);
88+
}
89+
__asm__ volatile (
90+
"fence\n"
91+
"fence.i\n"
92+
);
93+
94+
return 0;
95+
}
96+
97+
int arch_dcache_flush_all(void)
98+
{
99+
__asm__ volatile (
100+
"fence\n"
101+
/* th.dcache.call */
102+
".insn 0x10000B\n"
103+
"fence\n"
104+
);
105+
106+
return 0;
107+
}
108+
109+
static void arch_cache_clean_dcache_line(uintptr_t address_in)
110+
{
111+
register uintptr_t address __asm__("a3") = address_in;
112+
113+
__asm__ volatile (
114+
/* th.dcache.cpa a3*/
115+
".insn 0x296800B\n"
116+
:
117+
: "r"(address)
118+
);
119+
}
120+
121+
int arch_dcache_flush_range(void *addr_in, size_t size)
122+
{
123+
uintptr_t addr = (uintptr_t)addr_in;
124+
125+
__asm__ volatile (
126+
"fence\n"
127+
);
128+
for (uintptr_t i = addr; i < addr + size; i += CONFIG_DCACHE_LINE_SIZE) {
129+
arch_cache_clean_dcache_line(i);
130+
}
131+
__asm__ volatile (
132+
"fence\n"
133+
);
134+
135+
return 0;
136+
}
137+
138+
int arch_dcache_flush_and_invd_all(void)
139+
{
140+
__asm__ volatile (
141+
"fence\n"
142+
/* th.dcache.ciall */
143+
".insn 0x30000B\n"
144+
"fence\n"
145+
);
146+
147+
return 0;
148+
}
149+
150+
static void arch_cache_clean_invalidate_dcache_line(uintptr_t address_in)
151+
{
152+
register uintptr_t address __asm__("a3") = address_in;
153+
154+
__asm__ volatile (
155+
/* th.dcache.cipa a3*/
156+
".insn 0x2B6800B\n"
157+
:
158+
: "r"(address)
159+
);
160+
}
161+
162+
int arch_dcache_flush_and_invd_range(void *addr_in, size_t size)
163+
{
164+
uintptr_t addr = (uintptr_t)addr_in;
165+
166+
__asm__ volatile (
167+
"fence\n"
168+
);
169+
for (uintptr_t i = addr; i < addr + size; i += CONFIG_DCACHE_LINE_SIZE) {
170+
arch_cache_clean_invalidate_dcache_line(i);
171+
}
172+
__asm__ volatile (
173+
"fence\n"
174+
);
175+
176+
return 0;
177+
}
178+
179+
int arch_icache_flush_all(void)
180+
{
181+
return -ENOTSUP;
182+
}
183+
184+
int arch_icache_flush_and_invd_all(void)
185+
{
186+
return -ENOTSUP;
187+
}
188+
189+
int arch_icache_flush_range(void *addr, size_t size)
190+
{
191+
ARG_UNUSED(addr);
192+
ARG_UNUSED(size);
193+
194+
return -ENOTSUP;
195+
}
196+
197+
int arch_icache_flush_and_invd_range(void *addr, size_t size)
198+
{
199+
ARG_UNUSED(addr);
200+
ARG_UNUSED(size);
201+
202+
return -ENOTSUP;
203+
}
Lines changed: 108 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,108 @@
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/cache.h>
10+
11+
/* "a Hardware CSR" */
12+
#define THEAD_MHCR "0x7C1"
13+
14+
void arch_icache_enable(void)
15+
{
16+
uint32_t tmp;
17+
18+
__asm__ volatile (
19+
"fence\n"
20+
"fence.i\n"
21+
/* th.icache.iall */
22+
".insn 0x100000B\n"
23+
);
24+
__asm__ volatile(
25+
"csrr %0, " THEAD_MHCR
26+
: "=r"(tmp));
27+
tmp |= (1 << 0);
28+
__asm__ volatile(
29+
"csrw " THEAD_MHCR ", %0"
30+
:
31+
: "r"(tmp));
32+
__asm__ volatile (
33+
"fence\n"
34+
"fence.i\n"
35+
);
36+
}
37+
38+
void arch_dcache_enable(void)
39+
{
40+
uint32_t tmp;
41+
42+
__asm__ volatile (
43+
"fence\n"
44+
"fence.i\n"
45+
/* th.dcache.iall */
46+
".insn 0x20000B\n"
47+
);
48+
__asm__ volatile(
49+
"csrr %0, " THEAD_MHCR
50+
: "=r"(tmp));
51+
tmp |= (1 << 1) | (1 << 2) | (1 << 3) | (1 << 4);
52+
__asm__ volatile(
53+
"csrw " THEAD_MHCR ", %0"
54+
:
55+
: "r"(tmp));
56+
__asm__ volatile (
57+
"fence\n"
58+
"fence.i\n"
59+
);
60+
}
61+
62+
void arch_icache_disable(void)
63+
{
64+
uint32_t tmp;
65+
66+
__asm__ volatile (
67+
"fence\n"
68+
"fence.i\n"
69+
/* th.icache.iall */
70+
".insn 0x100000B\n"
71+
);
72+
__asm__ volatile(
73+
"csrr %0, " THEAD_MHCR
74+
: "=r"(tmp));
75+
tmp &= ~(1 << 0);
76+
__asm__ volatile(
77+
"csrw " THEAD_MHCR ", %0"
78+
:
79+
: "r"(tmp));
80+
__asm__ volatile (
81+
"fence\n"
82+
"fence.i\n"
83+
);
84+
}
85+
86+
void arch_dcache_disable(void)
87+
{
88+
uint32_t tmp;
89+
90+
__asm__ volatile (
91+
"fence\n"
92+
"fence.i\n"
93+
/* th.dcache.iall */
94+
".insn 0x20000B\n"
95+
);
96+
__asm__ volatile(
97+
"csrr %0, " THEAD_MHCR
98+
: "=r"(tmp));
99+
tmp &= ~((1 << 1) | (1 << 2) | (1 << 3) | (1 << 4));
100+
__asm__ volatile(
101+
"csrw " THEAD_MHCR ", %0"
102+
:
103+
: "r"(tmp));
104+
__asm__ volatile (
105+
"fence\n"
106+
"fence.i\n"
107+
);
108+
}

0 commit comments

Comments
 (0)