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