1178172Simp/*	$NetBSD: cache.h,v 1.6 2003/02/17 11:35:01 simonb Exp $	*/
2178172Simp
3331722Seadler/*
4178172Simp * Copyright 2001 Wasabi Systems, Inc.
5178172Simp * All rights reserved.
6178172Simp *
7178172Simp * Written by Jason R. Thorpe for Wasabi Systems, Inc.
8178172Simp *
9178172Simp * Redistribution and use in source and binary forms, with or without
10178172Simp * modification, are permitted provided that the following conditions
11178172Simp * are met:
12178172Simp * 1. Redistributions of source code must retain the above copyright
13178172Simp *    notice, this list of conditions and the following disclaimer.
14178172Simp * 2. Redistributions in binary form must reproduce the above copyright
15178172Simp *    notice, this list of conditions and the following disclaimer in the
16178172Simp *    documentation and/or other materials provided with the distribution.
17178172Simp * 3. All advertising materials mentioning features or use of this software
18178172Simp *    must display the following acknowledgement:
19178172Simp *	This product includes software developed for the NetBSD Project by
20178172Simp *	Wasabi Systems, Inc.
21178172Simp * 4. The name of Wasabi Systems, Inc. may not be used to endorse
22178172Simp *    or promote products derived from this software without specific prior
23178172Simp *    written permission.
24178172Simp *
25178172Simp * THIS SOFTWARE IS PROVIDED BY WASABI SYSTEMS, INC. ``AS IS'' AND
26178172Simp * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
27178172Simp * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
28178172Simp * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL WASABI SYSTEMS, INC
29178172Simp * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
30178172Simp * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
31178172Simp * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
32178172Simp * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
33178172Simp * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
34178172Simp * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
35178172Simp * POSSIBILITY OF SUCH DAMAGE.
36178172Simp *
37178172Simp * $FreeBSD$
38178172Simp */
39178172Simp
40202031Simp#ifndef	_MACHINE_CACHE_H_
41202031Simp#define	_MACHINE_CACHE_H_
42202031Simp
43178172Simp/*
44178172Simp * Cache operations.
45178172Simp *
46178172Simp * We define the following primitives:
47178172Simp *
48178172Simp * --- Instruction cache synchronization (mandatory):
49178172Simp *
50178172Simp *	icache_sync_all		Synchronize I-cache
51178172Simp *
52178172Simp *	icache_sync_range	Synchronize I-cache range
53178172Simp *
54178172Simp *	icache_sync_range_index	(index ops)
55178172Simp *
56178172Simp * --- Primary data cache (mandatory):
57178172Simp *
58178172Simp *	pdcache_wbinv_all	Write-back Invalidate primary D-cache
59178172Simp *
60178172Simp *	pdcache_wbinv_range	Write-back Invalidate primary D-cache range
61178172Simp *
62178172Simp *	pdcache_wbinv_range_index (index ops)
63178172Simp *
64178172Simp *	pdcache_inv_range	Invalidate primary D-cache range
65178172Simp *
66178172Simp *	pdcache_wb_range	Write-back primary D-cache range
67178172Simp *
68178172Simp * --- Secondary data cache (optional):
69178172Simp *
70178172Simp *	sdcache_wbinv_all	Write-back Invalidate secondary D-cache
71178172Simp *
72178172Simp *	sdcache_wbinv_range	Write-back Invalidate secondary D-cache range
73178172Simp *
74178172Simp *	sdcache_wbinv_range_index (index ops)
75178172Simp *
76178172Simp *	sdcache_inv_range	Invalidate secondary D-cache range
77178172Simp *
78178172Simp *	sdcache_wb_range	Write-back secondary D-cache range
79178172Simp *
80178172Simp * There are some rules that must be followed:
81178172Simp *
82178172Simp *	I-cache Synch (all or range):
83178172Simp *		The goal is to synchronize the instruction stream,
84178172Simp *		so you may need to write-back dirty data cache
85178172Simp *		blocks first.  If a range is requested, and you
86178172Simp *		can't synchronize just a range, you have to hit
87178172Simp *		the whole thing.
88178172Simp *
89178172Simp *	D-cache Write-back Invalidate range:
90178172Simp *		If you can't WB-Inv a range, you must WB-Inv the
91178172Simp *		entire D-cache.
92178172Simp *
93178172Simp *	D-cache Invalidate:
94178172Simp *		If you can't Inv the D-cache without doing a
95178172Simp *		Write-back, YOU MUST PANIC.  This is to catch
96178172Simp *		errors in calling code.  Callers must be aware
97178172Simp *		of this scenario, and must handle it appropriately
98178172Simp *		(consider the bus_dma(9) operations).
99178172Simp *
100178172Simp *	D-cache Write-back:
101178172Simp *		If you can't Write-back without doing an invalidate,
102178172Simp *		that's fine.  Then treat this as a WB-Inv.  Skipping
103178172Simp *		the invalidate is merely an optimization.
104178172Simp *
105178172Simp *	All operations:
106178172Simp *		Valid virtual addresses must be passed to the
107178172Simp *		cache operation.
108178172Simp *
109178172Simp * Finally, these primitives are grouped together in reasonable
110178172Simp * ways.  For all operations described here, first the primary
111178172Simp * cache is frobbed, then the secondary cache frobbed, if the
112178172Simp * operation for the secondary cache exists.
113178172Simp *
114178172Simp *	mips_icache_sync_all	Synchronize I-cache
115178172Simp *
116178172Simp *	mips_icache_sync_range	Synchronize I-cache range
117178172Simp *
118178172Simp *	mips_icache_sync_range_index (index ops)
119178172Simp *
120178172Simp *	mips_dcache_wbinv_all	Write-back Invalidate D-cache
121178172Simp *
122178172Simp *	mips_dcache_wbinv_range	Write-back Invalidate D-cache range
123178172Simp *
124178172Simp *	mips_dcache_wbinv_range_index (index ops)
125178172Simp *
126178172Simp *	mips_dcache_inv_range	Invalidate D-cache range
127178172Simp *
128178172Simp *	mips_dcache_wb_range	Write-back D-cache range
129178172Simp */
130178172Simp
131178172Simpstruct mips_cache_ops {
132178172Simp	void	(*mco_icache_sync_all)(void);
133178172Simp	void	(*mco_icache_sync_range)(vm_offset_t, vm_size_t);
134178172Simp	void	(*mco_icache_sync_range_index)(vm_offset_t, vm_size_t);
135178172Simp
136178172Simp	void	(*mco_pdcache_wbinv_all)(void);
137178172Simp	void	(*mco_pdcache_wbinv_range)(vm_offset_t, vm_size_t);
138178172Simp	void	(*mco_pdcache_wbinv_range_index)(vm_offset_t, vm_size_t);
139178172Simp	void	(*mco_pdcache_inv_range)(vm_offset_t, vm_size_t);
140178172Simp	void	(*mco_pdcache_wb_range)(vm_offset_t, vm_size_t);
141178172Simp
142178172Simp	/* These are called only by the (mipsNN) icache functions. */
143178172Simp	void    (*mco_intern_pdcache_wbinv_all)(void);
144178172Simp	void    (*mco_intern_pdcache_wbinv_range_index)(vm_offset_t, vm_size_t);
145178172Simp	void    (*mco_intern_pdcache_wb_range)(vm_offset_t, vm_size_t);
146178172Simp
147178172Simp	void	(*mco_sdcache_wbinv_all)(void);
148178172Simp	void	(*mco_sdcache_wbinv_range)(vm_offset_t, vm_size_t);
149178172Simp	void	(*mco_sdcache_wbinv_range_index)(vm_offset_t, vm_size_t);
150178172Simp	void	(*mco_sdcache_inv_range)(vm_offset_t, vm_size_t);
151178172Simp	void	(*mco_sdcache_wb_range)(vm_offset_t, vm_size_t);
152178172Simp
153178172Simp	/* These are called only by the (mipsNN) icache functions. */
154178172Simp	void    (*mco_intern_sdcache_wbinv_all)(void);
155178172Simp	void    (*mco_intern_sdcache_wbinv_range_index)(vm_offset_t, vm_size_t);
156178172Simp	void    (*mco_intern_sdcache_wb_range)(vm_offset_t, vm_size_t);
157178172Simp};
158178172Simp
159178172Simpextern struct mips_cache_ops mips_cache_ops;
160178172Simp
161178172Simp/* PRIMARY CACHE VARIABLES */
162202031Simpextern int mips_picache_linesize;
163202031Simpextern int mips_pdcache_linesize;
164178172Simp
165178172Simp#define	__mco_noargs(prefix, x)						\
166178172Simpdo {									\
167178172Simp	(*mips_cache_ops.mco_ ## prefix ## p ## x )();			\
168178172Simp	if (*mips_cache_ops.mco_ ## prefix ## s ## x )			\
169178172Simp		(*mips_cache_ops.mco_ ## prefix ## s ## x )();		\
170178172Simp} while (/*CONSTCOND*/0)
171178172Simp
172178172Simp#define	__mco_2args(prefix, x, a, b)					\
173178172Simpdo {									\
174178172Simp	(*mips_cache_ops.mco_ ## prefix ## p ## x )((a), (b));		\
175178172Simp	if (*mips_cache_ops.mco_ ## prefix ## s ## x )			\
176178172Simp		(*mips_cache_ops.mco_ ## prefix ## s ## x )((a), (b));	\
177178172Simp} while (/*CONSTCOND*/0)
178178172Simp
179178172Simp#define	mips_icache_sync_all()						\
180178172Simp	(*mips_cache_ops.mco_icache_sync_all)()
181178172Simp
182178172Simp#define	mips_icache_sync_range(v, s)					\
183178172Simp	(*mips_cache_ops.mco_icache_sync_range)((v), (s))
184178172Simp
185178172Simp#define	mips_icache_sync_range_index(v, s)				\
186178172Simp	(*mips_cache_ops.mco_icache_sync_range_index)((v), (s))
187178172Simp
188178172Simp#define	mips_dcache_wbinv_all()						\
189178172Simp	__mco_noargs(, dcache_wbinv_all)
190178172Simp
191178172Simp#define	mips_dcache_wbinv_range(v, s)					\
192178172Simp	__mco_2args(, dcache_wbinv_range, (v), (s))
193178172Simp
194178172Simp#define	mips_dcache_wbinv_range_index(v, s)				\
195178172Simp	__mco_2args(, dcache_wbinv_range_index, (v), (s))
196178172Simp
197178172Simp#define	mips_dcache_inv_range(v, s)					\
198178172Simp	__mco_2args(, dcache_inv_range, (v), (s))
199178172Simp
200178172Simp#define	mips_dcache_wb_range(v, s)					\
201178172Simp	__mco_2args(, dcache_wb_range, (v), (s))
202178172Simp
203178172Simp/*
204178172Simp * Private D-cache functions only called from (currently only the
205178172Simp * mipsNN) I-cache functions.
206178172Simp */
207178172Simp#define mips_intern_dcache_wbinv_all()					\
208178172Simp	__mco_noargs(intern_, dcache_wbinv_all)
209178172Simp
210178172Simp#define mips_intern_dcache_wbinv_range_index(v, s)			\
211178172Simp	__mco_2args(intern_, dcache_wbinv_range_index, (v), (s))
212178172Simp
213178172Simp#define mips_intern_dcache_wb_range(v, s)				\
214178172Simp	__mco_2args(intern_, dcache_wb_range, (v), (s))
215178172Simp
216178172Simp/* forward declaration */
217178172Simpstruct mips_cpuinfo;
218178172Simp
219178172Simpvoid    mips_config_cache(struct mips_cpuinfo *);
220178172Simp
221178172Simp#include <machine/cache_mipsNN.h>
222202031Simp#endif	/* _MACHINE_CACHE_H_ */
223