Skip to content

Commit 3761359

Browse files
committed
risc-v: handle T-Head L1 caches
Provide and use hooks for L1 cache operations on the T-Head processors. Re-worked from diffs provided by Rui-Xiang Guo via port-riscv.
1 parent 74a0bd7 commit 3761359

7 files changed

Lines changed: 238 additions & 53 deletions

File tree

sys/arch/riscv/conf/files.riscv

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
# $NetBSD: files.riscv,v 1.17 2025/01/01 17:53:07 skrll Exp $
1+
# $NetBSD: files.riscv,v 1.18 2026/03/18 06:41:40 skrll Exp $
22
#
33

44
maxpartitions 16
@@ -28,6 +28,7 @@ file arch/riscv/riscv/clock_machdep.c
2828
file arch/riscv/riscv/copy.S
2929
file arch/riscv/riscv/core_machdep.c coredump
3030
file arch/riscv/riscv/cpu.c cpu
31+
file arch/riscv/riscv/cpufunc.c
3132
file arch/riscv/riscv/cpu_subr.c
3233
file arch/riscv/riscv/cpu_switch.S
3334
file arch/riscv/riscv/db_interface.c ddb

sys/arch/riscv/include/cpufunc.h

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
/* $NetBSD: cpufunc.h,v 1.1 2023/05/07 12:41:48 skrll Exp $ */
1+
/* $NetBSD: cpufunc.h,v 1.2 2026/03/18 06:41:41 skrll Exp $ */
22

33
/*-
44
* Copyright (c) 2023 The NetBSD Foundation, Inc.
@@ -35,13 +35,15 @@
3535
#ifdef _KERNEL
3636

3737
#include <sys/cdefs.h>
38-
__KERNEL_RCSID(0, "$NetBSD: cpufunc.h,v 1.1 2023/05/07 12:41:48 skrll Exp $");
38+
__KERNEL_RCSID(0, "$NetBSD: cpufunc.h,v 1.2 2026/03/18 06:41:41 skrll Exp $");
3939

4040
#include <sys/param.h>
4141

4242
#include <sys/bus.h>
4343
#include <sys/cpu.h>
4444

45+
int set_cpufuncs(void);
46+
4547
/* cache op */
4648
#define cpu_dcache_wbinv_all() __nothing
4749
#define cpu_dcache_inv_all() __nothing
@@ -50,12 +52,13 @@ __KERNEL_RCSID(0, "$NetBSD: cpufunc.h,v 1.1 2023/05/07 12:41:48 skrll Exp $");
5052
#define cpu_icache_sync_all() __nothing
5153
#define cpu_icache_inv_all() __nothing
5254

53-
#define cpu_dcache_wbinv_range(v,s) __nothing
54-
#define cpu_dcache_inv_range(v,s) __nothing
55-
#define cpu_dcache_wb_range(v,s) __nothing
5655
#define cpu_idcache_wbinv_range(v,s) __nothing
5756
#define cpu_icache_sync_range(v,s) __nothing
5857

58+
extern void (*cpu_dcache_wbinv_range)(vaddr_t, vsize_t);
59+
extern void (*cpu_dcache_inv_range)(vaddr_t, vsize_t);
60+
extern void (*cpu_dcache_wb_range)(vaddr_t, vsize_t);
61+
5962
extern void (*cpu_sdcache_wbinv_range)(vaddr_t, paddr_t, psize_t);
6063
extern void (*cpu_sdcache_inv_range)(vaddr_t, paddr_t, psize_t);
6164
extern void (*cpu_sdcache_wb_range)(vaddr_t, paddr_t, psize_t);

sys/arch/riscv/include/pmap.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
/* $NetBSD: pmap.h,v 1.25 2025/10/12 04:08:26 thorpej Exp $ */
1+
/* $NetBSD: pmap.h,v 1.26 2026/03/18 06:41:41 skrll Exp $ */
22

33
/*
44
* Copyright (c) 2014, 2019, 2021 The NetBSD Foundation, Inc.
@@ -153,7 +153,7 @@ void pmap_md_tlb_info_attach(struct pmap_tlb_info *, struct cpu_info *);
153153
void pmap_md_xtab_activate(struct pmap *, struct lwp *);
154154
void pmap_md_xtab_deactivate(struct pmap *);
155155

156-
void pmap_probe_pbmt(void);
156+
void pmap_pte_xmae(void);
157157
void pmap_bootstrap(vaddr_t, vaddr_t);
158158

159159
vsize_t pmap_kenter_range(vaddr_t, paddr_t, vsize_t, vm_prot_t, u_int);

sys/arch/riscv/riscv/cpu.c

Lines changed: 2 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
/* $NetBSD: cpu.c,v 1.10 2025/10/12 04:08:26 thorpej Exp $ */
1+
/* $NetBSD: cpu.c,v 1.11 2026/03/18 06:41:41 skrll Exp $ */
22

33
/*-
44
* Copyright (c) 2023 The NetBSD Foundation, Inc.
@@ -32,7 +32,7 @@
3232
#include "opt_multiprocessor.h"
3333

3434
#include <sys/cdefs.h>
35-
__KERNEL_RCSID(0, "$NetBSD: cpu.c,v 1.10 2025/10/12 04:08:26 thorpej Exp $");
35+
__KERNEL_RCSID(0, "$NetBSD: cpu.c,v 1.11 2026/03/18 06:41:41 skrll Exp $");
3636

3737
#include <sys/param.h>
3838

@@ -54,18 +54,6 @@ __KERNEL_RCSID(0, "$NetBSD: cpu.c,v 1.10 2025/10/12 04:08:26 thorpej Exp $");
5454
#define NCPUINFO 1
5555
#endif /* MULTIPROCESSOR */
5656

57-
static void
58-
cache_nullop(vaddr_t va, paddr_t pa, psize_t sz)
59-
{
60-
}
61-
62-
void (*cpu_sdcache_wbinv_range)(vaddr_t, paddr_t, psize_t) = cache_nullop;
63-
void (*cpu_sdcache_inv_range)(vaddr_t, paddr_t, psize_t) = cache_nullop;
64-
void (*cpu_sdcache_wb_range)(vaddr_t, paddr_t, psize_t) = cache_nullop;
65-
66-
u_int riscv_dcache_align = CACHE_LINE_SIZE;
67-
u_int riscv_dcache_align_mask = CACHE_LINE_SIZE - 1;
68-
6957
struct cpu_arch {
7058
uint64_t ca_id;
7159
const char *ca_name;

sys/arch/riscv/riscv/cpufunc.c

Lines changed: 209 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,209 @@
1+
/* $NetBSD: cpufunc.c,v 1.1 2026/03/18 06:41:41 skrll Exp $ */
2+
3+
/*-
4+
* Copyright (c) 2026 The NetBSD Foundation, Inc.
5+
* All rights reserved.
6+
*
7+
* This code is derived from software contributed to The NetBSD Foundation
8+
* by Nick Hudson
9+
*
10+
* Redistribution and use in source and binary forms, with or without
11+
* modification, are permitted provided that the following conditions
12+
* are met:
13+
* 1. Redistributions of source code must retain the above copyright
14+
* notice, this list of conditions and the following disclaimer.
15+
* 2. Redistributions in binary form must reproduce the above copyright
16+
* notice, this list of conditions and the following disclaimer in the
17+
* documentation and/or other materials provided with the distribution.
18+
*
19+
* THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
20+
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
21+
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
22+
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
23+
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
24+
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
25+
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
26+
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
27+
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
28+
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
29+
* POSSIBILITY OF SUCH DAMAGE.
30+
*/
31+
32+
33+
/*-
34+
* Copyright (c) 2026 Rui-Xiang Guo
35+
* All rights reserved.
36+
*
37+
* Redistribution and use in source and binary forms, with or without
38+
* modification, are permitted provided that the following conditions
39+
* are met:
40+
* 1. Redistributions of source code must retain the above copyright
41+
* notice, this list of conditions and the following disclaimer.
42+
* 2. Redistributions in binary form must reproduce the above copyright
43+
* notice, this list of conditions and the following disclaimer in the
44+
* documentation and/or other materials provided with the distribution.
45+
*
46+
* THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
47+
* ``AS IS'' AND ANY EXPRESS OR IMPLinIED WARRANTIES, INCLUDING, BUT NOT LIMITED
48+
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
49+
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
50+
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
51+
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
52+
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
53+
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
54+
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
55+
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
56+
* POSSIBILITY OF SUCH DAMAGE.
57+
*/
58+
59+
#include "opt_riscv_debug.h"
60+
61+
#include <sys/cdefs.h>
62+
__KERNEL_RCSID(0, "$NetBSD: cpufunc.c,v 1.1 2026/03/18 06:41:41 skrll Exp $");
63+
64+
#include <sys/param.h>
65+
#include <sys/types.h>
66+
67+
#include <uvm/uvm_extern.h>
68+
69+
#include <riscv/cpufunc.h>
70+
#include <riscv/sbi.h>
71+
72+
#ifdef VERBOSE_INIT_RISCV
73+
#define VPRINTF(...) printf(__VA_ARGS__)
74+
#else
75+
#define VPRINTF(...) __nothing
76+
#endif
77+
78+
static void
79+
cache_nullop(vaddr_t va, psize_t sz)
80+
{
81+
}
82+
83+
static void
84+
scache_nullop(vaddr_t va, paddr_t pa, psize_t sz)
85+
{
86+
}
87+
88+
void (*cpu_dcache_wbinv_range)(vaddr_t, psize_t) = cache_nullop;
89+
void (*cpu_dcache_inv_range)(vaddr_t, psize_t) = cache_nullop;
90+
void (*cpu_dcache_wb_range)(vaddr_t, psize_t) = cache_nullop;
91+
92+
void (*cpu_sdcache_wbinv_range)(vaddr_t, paddr_t, psize_t) = scache_nullop;
93+
void (*cpu_sdcache_inv_range)(vaddr_t, paddr_t, psize_t) = scache_nullop;
94+
void (*cpu_sdcache_wb_range)(vaddr_t, paddr_t, psize_t) = scache_nullop;
95+
96+
u_int riscv_dcache_align = CACHE_LINE_SIZE;
97+
u_int riscv_dcache_align_mask = CACHE_LINE_SIZE - 1;
98+
99+
static void
100+
thead_dcache_wbinv_range(vaddr_t va, vsize_t sz)
101+
{
102+
const u_int line_size = riscv_dcache_align;
103+
104+
KASSERT(powerof2(line_size));
105+
KASSERT(sz != 0);
106+
107+
const vaddr_t sva = rounddown2(va, line_size);
108+
const vaddr_t eva = roundup2(va + sz, line_size);
109+
110+
for (vaddr_t addr = sva; addr < eva; addr += line_size) {
111+
asm volatile(
112+
"mv a0, %0\n"
113+
".long 0x0275000b\n" /* dcache.civa a0 */
114+
:
115+
: "r"(addr)
116+
: "a0","memory");
117+
}
118+
119+
asm volatile("fence rw, rw" ::: "memory");
120+
}
121+
122+
static void
123+
thead_dcache_inv_range(vaddr_t va, vsize_t sz)
124+
{
125+
const u_int line_size = riscv_dcache_align;
126+
127+
KASSERT(powerof2(line_size));
128+
KASSERT(sz != 0);
129+
130+
const vaddr_t sva = rounddown2(va, line_size);
131+
const vaddr_t eva = roundup2(va + sz, line_size);
132+
133+
for (vaddr_t addr = sva; addr < eva; addr += line_size) {
134+
asm volatile(
135+
"mv a0, %0\n"
136+
".long 0x0265000b\n" /* dcache.iva a0 */
137+
:
138+
: "r"(addr)
139+
: "a0", "memory");
140+
}
141+
142+
asm volatile("fence rw, rw" ::: "memory");
143+
}
144+
145+
static void
146+
thead_dcache_wb_range(vaddr_t va, vsize_t sz)
147+
{
148+
const u_int line_size = riscv_dcache_align;
149+
150+
KASSERT(powerof2(line_size));
151+
KASSERT(sz != 0);
152+
153+
const vaddr_t sva = rounddown2(va, line_size);
154+
const vaddr_t eva = roundup2(va + sz, line_size);
155+
156+
for (vaddr_t addr = sva; addr < eva; addr += line_size) {
157+
asm volatile(
158+
"mv a0, %0\n"
159+
".long 0x0245000b\n" /* dcache.cva a0 */
160+
:
161+
: "r"(addr)
162+
: "a0", "memory");
163+
}
164+
165+
asm volatile("fence rw, rw" ::: "memory");
166+
}
167+
168+
169+
/*
170+
* This is only called on the BP.
171+
*/
172+
int
173+
set_cpufuncs(void)
174+
{
175+
const register_t mvendorid = sbi_get_mvendorid().value;
176+
177+
switch (mvendorid) {
178+
case CPU_VENDOR_THEAD:
179+
#ifdef _LP64
180+
/*
181+
* Critical to do this before mucking around with any more
182+
* mappings.
183+
*/
184+
if (csr_thead_sxstatus_read() & TX_SXSTATUS_MAEE) {
185+
VPRINTF("T-Head XMAE detected.\n");
186+
pmap_pte_xmae();
187+
}
188+
/*
189+
* No fixups of the initial MMU tables. We have to assume
190+
* that those were set up correctly in locore.S. The variables
191+
* set above are for new mappings created now that the kernel
192+
* is up and running.
193+
*/
194+
#endif
195+
196+
cpu_dcache_wbinv_range = thead_dcache_wbinv_range;
197+
cpu_dcache_inv_range = thead_dcache_inv_range;
198+
cpu_dcache_wb_range = thead_dcache_wb_range;
199+
200+
201+
break;
202+
default:
203+
break;
204+
}
205+
206+
207+
return 0;
208+
}
209+

sys/arch/riscv/riscv/pmap_machdep.c

Lines changed: 7 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
/* $NetBSD: pmap_machdep.c,v 1.23 2025/10/12 19:44:04 skrll Exp $ */
1+
/* $NetBSD: pmap_machdep.c,v 1.24 2026/03/18 06:41:41 skrll Exp $ */
22

33
/*
44
* Copyright (c) 2014, 2019, 2021 The NetBSD Foundation, Inc.
@@ -36,7 +36,7 @@
3636
#define __PMAP_PRIVATE
3737

3838
#include <sys/cdefs.h>
39-
__RCSID("$NetBSD: pmap_machdep.c,v 1.23 2025/10/12 19:44:04 skrll Exp $");
39+
__RCSID("$NetBSD: pmap_machdep.c,v 1.24 2026/03/18 06:41:41 skrll Exp $");
4040

4141
#include <sys/param.h>
4242
#include <sys/buf.h>
@@ -321,32 +321,13 @@ pmap_md_grow(pmap_pdetab_t *ptb, vaddr_t va, vsize_t vshift,
321321
}
322322

323323
void
324-
pmap_probe_pbmt(void)
324+
pmap_pte_xmae(void)
325325
{
326326
#ifdef _LP64
327-
const register_t mvendorid = sbi_get_mvendorid().value;
328-
329-
switch (mvendorid) {
330-
case CPU_VENDOR_THEAD:
331-
if (csr_thead_sxstatus_read() & TX_SXSTATUS_MAEE) {
332-
VPRINTF("T-Head XMAE detected.\n");
333-
pmap_pte_pbmt_mask = PTE_XMAE;
334-
pmap_pte_pma = PTE_XMAE_PMA;
335-
pmap_pte_nc = PTE_XMAE_NC;
336-
pmap_pte_io = PTE_XMAE_IO;
337-
}
338-
break;
339-
340-
default:
341-
break;
342-
}
343-
344-
/*
345-
* No fixups of the initial MMU tables. We have to assume
346-
* that those were set up correctly in locore.S. The variables
347-
* set above are for new mappings created now that the kernel
348-
* is up and running.
349-
*/
327+
pmap_pte_pbmt_mask = PTE_XMAE;
328+
pmap_pte_pma = PTE_XMAE_PMA;
329+
pmap_pte_nc = PTE_XMAE_NC;
330+
pmap_pte_io = PTE_XMAE_IO;
350331
#endif
351332
}
352333

0 commit comments

Comments
 (0)