xref: /netbsd-src/sys/arch/powerpc/booke/booke_cache.c (revision 16031f7d46f56c21335839c17974dddd9f9800b4)
1*16031f7dSrin /*	$NetBSD: booke_cache.c,v 1.5 2020/07/06 09:34:16 rin Exp $	*/
2b8ea2c8cSmatt /*-
3b8ea2c8cSmatt  * Copyright (c) 2010, 2011 The NetBSD Foundation, Inc.
4b8ea2c8cSmatt  * All rights reserved.
5b8ea2c8cSmatt  *
6b8ea2c8cSmatt  * This code is derived from software contributed to The NetBSD Foundation
7b8ea2c8cSmatt  * by Raytheon BBN Technologies Corp and Defense Advanced Research Projects
8b8ea2c8cSmatt  * Agency and which was developed by Matt Thomas of 3am Software Foundry.
9b8ea2c8cSmatt  *
10b8ea2c8cSmatt  * This material is based upon work supported by the Defense Advanced Research
11b8ea2c8cSmatt  * Projects Agency and Space and Naval Warfare Systems Center, Pacific, under
12b8ea2c8cSmatt  * Contract No. N66001-09-C-2073.
13b8ea2c8cSmatt  * Approved for Public Release, Distribution Unlimited
14b8ea2c8cSmatt  *
15b8ea2c8cSmatt  * Redistribution and use in source and binary forms, with or without
16b8ea2c8cSmatt  * modification, are permitted provided that the following conditions
17b8ea2c8cSmatt  * are met:
18b8ea2c8cSmatt  * 1. Redistributions of source code must retain the above copyright
19b8ea2c8cSmatt  *    notice, this list of conditions and the following disclaimer.
20b8ea2c8cSmatt  * 2. Redistributions in binary form must reproduce the above copyright
21b8ea2c8cSmatt  *    notice, this list of conditions and the following disclaimer in the
22b8ea2c8cSmatt  *    documentation and/or other materials provided with the distribution.
23b8ea2c8cSmatt  *
24b8ea2c8cSmatt  * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
25b8ea2c8cSmatt  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
26b8ea2c8cSmatt  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
27b8ea2c8cSmatt  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
28b8ea2c8cSmatt  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
29b8ea2c8cSmatt  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
30b8ea2c8cSmatt  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
31b8ea2c8cSmatt  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
32b8ea2c8cSmatt  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
33b8ea2c8cSmatt  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
34b8ea2c8cSmatt  * POSSIBILITY OF SUCH DAMAGE.
35b8ea2c8cSmatt  */
36b8ea2c8cSmatt 
37*16031f7dSrin #include <sys/cdefs.h>
38*16031f7dSrin __KERNEL_RCSID(0, "$NetBSD: booke_cache.c,v 1.5 2020/07/06 09:34:16 rin Exp $");
39b8ea2c8cSmatt 
40b8ea2c8cSmatt #include <sys/param.h>
41b8ea2c8cSmatt #include <sys/cpu.h>
424d4e79f0Smatt #include <sys/atomic.h>
43b8ea2c8cSmatt 
444d4e79f0Smatt enum cache_op { OP_DCBF, OP_DCBST, OP_DCBI, OP_DCBZ, OP_DCBA, OP_ICBI };
45b8ea2c8cSmatt 
46b8ea2c8cSmatt static void inline
dcbf(vaddr_t va,vsize_t off)47b8ea2c8cSmatt dcbf(vaddr_t va, vsize_t off)
48b8ea2c8cSmatt {
49b8ea2c8cSmatt 	__asm volatile("dcbf\t%0,%1" : : "b" (va), "r" (off));
50b8ea2c8cSmatt }
51b8ea2c8cSmatt 
52b8ea2c8cSmatt static void inline
dcbst(vaddr_t va,vsize_t off)53b8ea2c8cSmatt dcbst(vaddr_t va, vsize_t off)
54b8ea2c8cSmatt {
55b8ea2c8cSmatt 	__asm volatile("dcbst\t%0,%1" : : "b" (va), "r" (off));
56b8ea2c8cSmatt }
57b8ea2c8cSmatt 
58b8ea2c8cSmatt static void inline
dcbi(vaddr_t va,vsize_t off)59b8ea2c8cSmatt dcbi(vaddr_t va, vsize_t off)
60b8ea2c8cSmatt {
61b8ea2c8cSmatt 	__asm volatile("dcbi\t%0,%1" : : "b" (va), "r" (off));
62b8ea2c8cSmatt }
63b8ea2c8cSmatt 
64b8ea2c8cSmatt static void inline
dcbz(vaddr_t va,vsize_t off)65b8ea2c8cSmatt dcbz(vaddr_t va, vsize_t off)
66b8ea2c8cSmatt {
67b8ea2c8cSmatt 	__asm volatile("dcbz\t%0,%1" : : "b" (va), "r" (off));
68b8ea2c8cSmatt }
69b8ea2c8cSmatt 
70b8ea2c8cSmatt static void inline
dcba(vaddr_t va,vsize_t off)71b8ea2c8cSmatt dcba(vaddr_t va, vsize_t off)
72b8ea2c8cSmatt {
73b8ea2c8cSmatt 	__asm volatile("dcba\t%0,%1" : : "b" (va), "r" (off));
74b8ea2c8cSmatt }
75b8ea2c8cSmatt 
76b8ea2c8cSmatt static void inline
icbi(vaddr_t va,vsize_t off)77b8ea2c8cSmatt icbi(vaddr_t va, vsize_t off)
78b8ea2c8cSmatt {
79b8ea2c8cSmatt 	__asm volatile("icbi\t%0,%1" : : "b" (va), "r" (off));
80b8ea2c8cSmatt }
81b8ea2c8cSmatt 
82b8ea2c8cSmatt static inline void
cache_op(vaddr_t va,vsize_t len,vsize_t line_size,enum cache_op op)834d4e79f0Smatt cache_op(vaddr_t va, vsize_t len, vsize_t line_size, enum cache_op op)
84b8ea2c8cSmatt {
85b8ea2c8cSmatt 	KASSERT(line_size > 0);
86b8ea2c8cSmatt 
87b8ea2c8cSmatt 	if (len == 0)
88b8ea2c8cSmatt 		return;
89b8ea2c8cSmatt 
90b8ea2c8cSmatt 	/* Make sure we flush all cache lines */
91b8ea2c8cSmatt 	len += va & (line_size - 1);
92b8ea2c8cSmatt 	va &= -line_size;
93b8ea2c8cSmatt 
944d4e79f0Smatt 	for (vsize_t i = 0; i < len; i += line_size) {
954d4e79f0Smatt 		switch (op) {
964d4e79f0Smatt 		case OP_DCBF: dcbf(va, i); break;
974d4e79f0Smatt 		case OP_DCBST: dcbst(va, i); break;
984d4e79f0Smatt 		case OP_DCBI: dcbi(va, i); break;
994d4e79f0Smatt 		case OP_DCBZ: dcbz(va, i); break;
1004d4e79f0Smatt 		case OP_DCBA: dcba(va, i); break;
1014d4e79f0Smatt 		case OP_ICBI: icbi(va, i); break;
1024d4e79f0Smatt 		}
1034d4e79f0Smatt 	}
1044d4e79f0Smatt 	if (op != OP_ICBI)
1054d4e79f0Smatt 		membar_producer();
106b8ea2c8cSmatt }
107b8ea2c8cSmatt 
108b8ea2c8cSmatt void
dcache_wb_page(vaddr_t va)109b8ea2c8cSmatt dcache_wb_page(vaddr_t va)
110b8ea2c8cSmatt {
1114d4e79f0Smatt 	cache_op(va, PAGE_SIZE, curcpu()->ci_ci.dcache_line_size, OP_DCBST);
112b8ea2c8cSmatt }
113b8ea2c8cSmatt 
114b8ea2c8cSmatt void
dcache_wbinv_page(vaddr_t va)115b8ea2c8cSmatt dcache_wbinv_page(vaddr_t va)
116b8ea2c8cSmatt {
1174d4e79f0Smatt 	cache_op(va, PAGE_SIZE, curcpu()->ci_ci.dcache_line_size, OP_DCBF);
118b8ea2c8cSmatt }
119b8ea2c8cSmatt 
120b8ea2c8cSmatt void
dcache_inv_page(vaddr_t va)121b8ea2c8cSmatt dcache_inv_page(vaddr_t va)
122b8ea2c8cSmatt {
1234d4e79f0Smatt 	cache_op(va, PAGE_SIZE, curcpu()->ci_ci.dcache_line_size, OP_DCBI);
124b8ea2c8cSmatt }
125b8ea2c8cSmatt 
126b8ea2c8cSmatt void
dcache_zero_page(vaddr_t va)127b8ea2c8cSmatt dcache_zero_page(vaddr_t va)
128b8ea2c8cSmatt {
1294d4e79f0Smatt 	cache_op(va, PAGE_SIZE, curcpu()->ci_ci.dcache_line_size, OP_DCBZ);
130b8ea2c8cSmatt }
131b8ea2c8cSmatt 
132b8ea2c8cSmatt void
icache_inv_page(vaddr_t va)133b8ea2c8cSmatt icache_inv_page(vaddr_t va)
134b8ea2c8cSmatt {
1354d4e79f0Smatt 	membar_sync();
1364d4e79f0Smatt 	cache_op(va, PAGE_SIZE, curcpu()->ci_ci.icache_line_size, OP_ICBI);
1374d4e79f0Smatt 	membar_sync();
138b8ea2c8cSmatt 	/* synchronizing instruction will be the rfi to user mode */
139b8ea2c8cSmatt }
140b8ea2c8cSmatt 
141b8ea2c8cSmatt void
dcache_wb(vaddr_t va,vsize_t len)142b8ea2c8cSmatt dcache_wb(vaddr_t va, vsize_t len)
143b8ea2c8cSmatt {
1444d4e79f0Smatt 	cache_op(va, len, curcpu()->ci_ci.dcache_line_size, OP_DCBST);
145b8ea2c8cSmatt }
146b8ea2c8cSmatt 
147b8ea2c8cSmatt void
dcache_wbinv(vaddr_t va,vsize_t len)148b8ea2c8cSmatt dcache_wbinv(vaddr_t va, vsize_t len)
149b8ea2c8cSmatt {
1504d4e79f0Smatt 	cache_op(va, len, curcpu()->ci_ci.dcache_line_size, OP_DCBF);
151b8ea2c8cSmatt }
152b8ea2c8cSmatt 
153b8ea2c8cSmatt void
dcache_inv(vaddr_t va,vsize_t len)154b8ea2c8cSmatt dcache_inv(vaddr_t va, vsize_t len)
155b8ea2c8cSmatt {
1564d4e79f0Smatt 	cache_op(va, len, curcpu()->ci_ci.dcache_line_size, OP_DCBI);
157b8ea2c8cSmatt }
158b8ea2c8cSmatt 
159b8ea2c8cSmatt void
icache_inv(vaddr_t va,vsize_t len)160b8ea2c8cSmatt icache_inv(vaddr_t va, vsize_t len)
161b8ea2c8cSmatt {
1624d4e79f0Smatt 	membar_sync();
1634d4e79f0Smatt 	cache_op(va, len, curcpu()->ci_ci.icache_line_size, OP_ICBI);
1644d4e79f0Smatt 	membar_sync();
165b8ea2c8cSmatt }
166