cpufunc.h revision 244480
1129198Scognet/*	$NetBSD: cpufunc.h,v 1.29 2003/09/06 09:08:35 rearnsha Exp $	*/
2129198Scognet
3139735Simp/*-
4129198Scognet * Copyright (c) 1997 Mark Brinicombe.
5129198Scognet * Copyright (c) 1997 Causality Limited
6129198Scognet * All rights reserved.
7129198Scognet *
8129198Scognet * Redistribution and use in source and binary forms, with or without
9129198Scognet * modification, are permitted provided that the following conditions
10129198Scognet * are met:
11129198Scognet * 1. Redistributions of source code must retain the above copyright
12129198Scognet *    notice, this list of conditions and the following disclaimer.
13129198Scognet * 2. Redistributions in binary form must reproduce the above copyright
14129198Scognet *    notice, this list of conditions and the following disclaimer in the
15129198Scognet *    documentation and/or other materials provided with the distribution.
16129198Scognet * 3. All advertising materials mentioning features or use of this software
17129198Scognet *    must display the following acknowledgement:
18129198Scognet *	This product includes software developed by Causality Limited.
19129198Scognet * 4. The name of Causality Limited may not be used to endorse or promote
20129198Scognet *    products derived from this software without specific prior written
21129198Scognet *    permission.
22129198Scognet *
23129198Scognet * THIS SOFTWARE IS PROVIDED BY CAUSALITY LIMITED ``AS IS'' AND ANY EXPRESS
24129198Scognet * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
25129198Scognet * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
26129198Scognet * DISCLAIMED. IN NO EVENT SHALL CAUSALITY LIMITED BE LIABLE FOR ANY DIRECT,
27129198Scognet * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
28129198Scognet * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
29129198Scognet * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
30129198Scognet * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
31129198Scognet * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
32129198Scognet * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
33129198Scognet * SUCH DAMAGE.
34129198Scognet *
35129198Scognet * RiscBSD kernel project
36129198Scognet *
37129198Scognet * cpufunc.h
38129198Scognet *
39129198Scognet * Prototypes for cpu, mmu and tlb related functions.
40129198Scognet *
41129198Scognet * $FreeBSD: head/sys/arm/include/cpufunc.h 244480 2012-12-20 04:32:02Z gonzo $
42129198Scognet */
43129198Scognet
44129198Scognet#ifndef _MACHINE_CPUFUNC_H_
45129198Scognet#define _MACHINE_CPUFUNC_H_
46129198Scognet
47129198Scognet#ifdef _KERNEL
48129198Scognet
49129198Scognet#include <sys/types.h>
50129198Scognet#include <machine/cpuconf.h>
51132055Scognet#include <machine/katelib.h> /* For in[bwl] and out[bwl] */
52129198Scognet
53132055Scognetstatic __inline void
54132055Scognetbreakpoint(void)
55132055Scognet{
56137940Scognet	__asm(".word      0xe7ffffff");
57132055Scognet}
58132471Scognet
59129198Scognetstruct cpu_functions {
60129198Scognet
61129198Scognet	/* CPU functions */
62129198Scognet
63129198Scognet	u_int	(*cf_id)		(void);
64129198Scognet	void	(*cf_cpwait)		(void);
65129198Scognet
66129198Scognet	/* MMU functions */
67129198Scognet
68129198Scognet	u_int	(*cf_control)		(u_int bic, u_int eor);
69129198Scognet	void	(*cf_domains)		(u_int domains);
70129198Scognet	void	(*cf_setttb)		(u_int ttb);
71129198Scognet	u_int	(*cf_faultstatus)	(void);
72129198Scognet	u_int	(*cf_faultaddress)	(void);
73129198Scognet
74129198Scognet	/* TLB functions */
75129198Scognet
76129198Scognet	void	(*cf_tlb_flushID)	(void);
77129198Scognet	void	(*cf_tlb_flushID_SE)	(u_int va);
78129198Scognet	void	(*cf_tlb_flushI)	(void);
79129198Scognet	void	(*cf_tlb_flushI_SE)	(u_int va);
80129198Scognet	void	(*cf_tlb_flushD)	(void);
81129198Scognet	void	(*cf_tlb_flushD_SE)	(u_int va);
82129198Scognet
83129198Scognet	/*
84129198Scognet	 * Cache operations:
85129198Scognet	 *
86129198Scognet	 * We define the following primitives:
87129198Scognet	 *
88129198Scognet	 *	icache_sync_all		Synchronize I-cache
89129198Scognet	 *	icache_sync_range	Synchronize I-cache range
90129198Scognet	 *
91129198Scognet	 *	dcache_wbinv_all	Write-back and Invalidate D-cache
92129198Scognet	 *	dcache_wbinv_range	Write-back and Invalidate D-cache range
93129198Scognet	 *	dcache_inv_range	Invalidate D-cache range
94129198Scognet	 *	dcache_wb_range		Write-back D-cache range
95129198Scognet	 *
96129198Scognet	 *	idcache_wbinv_all	Write-back and Invalidate D-cache,
97129198Scognet	 *				Invalidate I-cache
98129198Scognet	 *	idcache_wbinv_range	Write-back and Invalidate D-cache,
99129198Scognet	 *				Invalidate I-cache range
100129198Scognet	 *
101129198Scognet	 * Note that the ARM term for "write-back" is "clean".  We use
102129198Scognet	 * the term "write-back" since it's a more common way to describe
103129198Scognet	 * the operation.
104129198Scognet	 *
105129198Scognet	 * There are some rules that must be followed:
106129198Scognet	 *
107129198Scognet	 *	I-cache Synch (all or range):
108129198Scognet	 *		The goal is to synchronize the instruction stream,
109129198Scognet	 *		so you may beed to write-back dirty D-cache blocks
110129198Scognet	 *		first.  If a range is requested, and you can't
111129198Scognet	 *		synchronize just a range, you have to hit the whole
112129198Scognet	 *		thing.
113129198Scognet	 *
114129198Scognet	 *	D-cache Write-Back and Invalidate range:
115129198Scognet	 *		If you can't WB-Inv a range, you must WB-Inv the
116129198Scognet	 *		entire D-cache.
117129198Scognet	 *
118129198Scognet	 *	D-cache Invalidate:
119129198Scognet	 *		If you can't Inv the D-cache, you must Write-Back
120129198Scognet	 *		and Invalidate.  Code that uses this operation
121129198Scognet	 *		MUST NOT assume that the D-cache will not be written
122129198Scognet	 *		back to memory.
123129198Scognet	 *
124129198Scognet	 *	D-cache Write-Back:
125129198Scognet	 *		If you can't Write-back without doing an Inv,
126129198Scognet	 *		that's fine.  Then treat this as a WB-Inv.
127129198Scognet	 *		Skipping the invalidate is merely an optimization.
128129198Scognet	 *
129129198Scognet	 *	All operations:
130129198Scognet	 *		Valid virtual addresses must be passed to each
131129198Scognet	 *		cache operation.
132129198Scognet	 */
133129198Scognet	void	(*cf_icache_sync_all)	(void);
134129198Scognet	void	(*cf_icache_sync_range)	(vm_offset_t, vm_size_t);
135129198Scognet
136129198Scognet	void	(*cf_dcache_wbinv_all)	(void);
137129198Scognet	void	(*cf_dcache_wbinv_range) (vm_offset_t, vm_size_t);
138129198Scognet	void	(*cf_dcache_inv_range)	(vm_offset_t, vm_size_t);
139129198Scognet	void	(*cf_dcache_wb_range)	(vm_offset_t, vm_size_t);
140129198Scognet
141129198Scognet	void	(*cf_idcache_wbinv_all)	(void);
142129198Scognet	void	(*cf_idcache_wbinv_range) (vm_offset_t, vm_size_t);
143171618Scognet	void	(*cf_l2cache_wbinv_all) (void);
144171618Scognet	void	(*cf_l2cache_wbinv_range) (vm_offset_t, vm_size_t);
145171618Scognet	void	(*cf_l2cache_inv_range)	  (vm_offset_t, vm_size_t);
146171618Scognet	void	(*cf_l2cache_wb_range)	  (vm_offset_t, vm_size_t);
147129198Scognet
148129198Scognet	/* Other functions */
149129198Scognet
150129198Scognet	void	(*cf_flush_prefetchbuf)	(void);
151129198Scognet	void	(*cf_drain_writebuf)	(void);
152129198Scognet	void	(*cf_flush_brnchtgt_C)	(void);
153129198Scognet	void	(*cf_flush_brnchtgt_E)	(u_int va);
154129198Scognet
155129198Scognet	void	(*cf_sleep)		(int mode);
156129198Scognet
157129198Scognet	/* Soft functions */
158129198Scognet
159129198Scognet	int	(*cf_dataabt_fixup)	(void *arg);
160129198Scognet	int	(*cf_prefetchabt_fixup)	(void *arg);
161129198Scognet
162129198Scognet	void	(*cf_context_switch)	(void);
163129198Scognet
164129198Scognet	void	(*cf_setup)		(char *string);
165129198Scognet};
166129198Scognet
167129198Scognetextern struct cpu_functions cpufuncs;
168129198Scognetextern u_int cputype;
169129198Scognet
170129198Scognet#define cpu_id()		cpufuncs.cf_id()
171129198Scognet#define	cpu_cpwait()		cpufuncs.cf_cpwait()
172129198Scognet
173129198Scognet#define cpu_control(c, e)	cpufuncs.cf_control(c, e)
174129198Scognet#define cpu_domains(d)		cpufuncs.cf_domains(d)
175129198Scognet#define cpu_setttb(t)		cpufuncs.cf_setttb(t)
176129198Scognet#define cpu_faultstatus()	cpufuncs.cf_faultstatus()
177129198Scognet#define cpu_faultaddress()	cpufuncs.cf_faultaddress()
178129198Scognet
179239268Sgonzo#ifndef SMP
180239268Sgonzo
181129198Scognet#define	cpu_tlb_flushID()	cpufuncs.cf_tlb_flushID()
182129198Scognet#define	cpu_tlb_flushID_SE(e)	cpufuncs.cf_tlb_flushID_SE(e)
183129198Scognet#define	cpu_tlb_flushI()	cpufuncs.cf_tlb_flushI()
184129198Scognet#define	cpu_tlb_flushI_SE(e)	cpufuncs.cf_tlb_flushI_SE(e)
185129198Scognet#define	cpu_tlb_flushD()	cpufuncs.cf_tlb_flushD()
186129198Scognet#define	cpu_tlb_flushD_SE(e)	cpufuncs.cf_tlb_flushD_SE(e)
187129198Scognet
188239268Sgonzo#else
189239268Sgonzovoid tlb_broadcast(int);
190239268Sgonzo
191239268Sgonzo#ifdef CPU_CORTEXA
192239268Sgonzo#define TLB_BROADCAST	/* No need to explicitely send an IPI */
193239268Sgonzo#else
194239268Sgonzo#define TLB_BROADCAST	tlb_broadcast(7)
195239268Sgonzo#endif
196239268Sgonzo
197239268Sgonzo#define	cpu_tlb_flushID() do { \
198239268Sgonzo	cpufuncs.cf_tlb_flushID(); \
199239268Sgonzo	TLB_BROADCAST; \
200239268Sgonzo} while(0)
201239268Sgonzo
202239268Sgonzo#define	cpu_tlb_flushID_SE(e) do { \
203239268Sgonzo	cpufuncs.cf_tlb_flushID_SE(e); \
204239268Sgonzo	TLB_BROADCAST; \
205239268Sgonzo} while(0)
206239268Sgonzo
207239268Sgonzo
208239268Sgonzo#define	cpu_tlb_flushI() do { \
209239268Sgonzo	cpufuncs.cf_tlb_flushI(); \
210239268Sgonzo	TLB_BROADCAST; \
211239268Sgonzo} while(0)
212239268Sgonzo
213239268Sgonzo
214239268Sgonzo#define	cpu_tlb_flushI_SE(e) do { \
215239268Sgonzo	cpufuncs.cf_tlb_flushI_SE(e); \
216239268Sgonzo	TLB_BROADCAST; \
217239268Sgonzo} while(0)
218239268Sgonzo
219239268Sgonzo
220239268Sgonzo#define	cpu_tlb_flushD() do { \
221239268Sgonzo	cpufuncs.cf_tlb_flushD(); \
222239268Sgonzo	TLB_BROADCAST; \
223239268Sgonzo} while(0)
224239268Sgonzo
225239268Sgonzo
226239268Sgonzo#define	cpu_tlb_flushD_SE(e) do { \
227239268Sgonzo	cpufuncs.cf_tlb_flushD_SE(e); \
228239268Sgonzo	TLB_BROADCAST; \
229239268Sgonzo} while(0)
230239268Sgonzo
231239268Sgonzo#endif
232239268Sgonzo
233129198Scognet#define	cpu_icache_sync_all()	cpufuncs.cf_icache_sync_all()
234129198Scognet#define	cpu_icache_sync_range(a, s) cpufuncs.cf_icache_sync_range((a), (s))
235129198Scognet
236129198Scognet#define	cpu_dcache_wbinv_all()	cpufuncs.cf_dcache_wbinv_all()
237129198Scognet#define	cpu_dcache_wbinv_range(a, s) cpufuncs.cf_dcache_wbinv_range((a), (s))
238129198Scognet#define	cpu_dcache_inv_range(a, s) cpufuncs.cf_dcache_inv_range((a), (s))
239129198Scognet#define	cpu_dcache_wb_range(a, s) cpufuncs.cf_dcache_wb_range((a), (s))
240129198Scognet
241129198Scognet#define	cpu_idcache_wbinv_all()	cpufuncs.cf_idcache_wbinv_all()
242129198Scognet#define	cpu_idcache_wbinv_range(a, s) cpufuncs.cf_idcache_wbinv_range((a), (s))
243171618Scognet#define cpu_l2cache_wbinv_all()	cpufuncs.cf_l2cache_wbinv_all()
244171618Scognet#define cpu_l2cache_wb_range(a, s) cpufuncs.cf_l2cache_wb_range((a), (s))
245171618Scognet#define cpu_l2cache_inv_range(a, s) cpufuncs.cf_l2cache_inv_range((a), (s))
246171618Scognet#define cpu_l2cache_wbinv_range(a, s) cpufuncs.cf_l2cache_wbinv_range((a), (s))
247129198Scognet
248129198Scognet#define	cpu_flush_prefetchbuf()	cpufuncs.cf_flush_prefetchbuf()
249129198Scognet#define	cpu_drain_writebuf()	cpufuncs.cf_drain_writebuf()
250129198Scognet#define	cpu_flush_brnchtgt_C()	cpufuncs.cf_flush_brnchtgt_C()
251129198Scognet#define	cpu_flush_brnchtgt_E(e)	cpufuncs.cf_flush_brnchtgt_E(e)
252129198Scognet
253129198Scognet#define cpu_sleep(m)		cpufuncs.cf_sleep(m)
254129198Scognet
255129198Scognet#define cpu_dataabt_fixup(a)		cpufuncs.cf_dataabt_fixup(a)
256129198Scognet#define cpu_prefetchabt_fixup(a)	cpufuncs.cf_prefetchabt_fixup(a)
257129198Scognet#define ABORT_FIXUP_OK		0	/* fixup succeeded */
258129198Scognet#define ABORT_FIXUP_FAILED	1	/* fixup failed */
259129198Scognet#define ABORT_FIXUP_RETURN	2	/* abort handler should return */
260129198Scognet
261129198Scognet#define cpu_setup(a)			cpufuncs.cf_setup(a)
262129198Scognet
263129198Scognetint	set_cpufuncs		(void);
264129198Scognet#define ARCHITECTURE_NOT_PRESENT	1	/* known but not configured */
265129198Scognet#define ARCHITECTURE_NOT_SUPPORTED	2	/* not known */
266129198Scognet
267129198Scognetvoid	cpufunc_nullop		(void);
268129198Scognetint	cpufunc_null_fixup	(void *);
269129198Scognetint	early_abort_fixup	(void *);
270129198Scognetint	late_abort_fixup	(void *);
271129198Scognetu_int	cpufunc_id		(void);
272239268Sgonzou_int	cpufunc_cpuid		(void);
273129198Scognetu_int	cpufunc_control		(u_int clear, u_int bic);
274129198Scognetvoid	cpufunc_domains		(u_int domains);
275129198Scognetu_int	cpufunc_faultstatus	(void);
276129198Scognetu_int	cpufunc_faultaddress	(void);
277239268Sgonzou_int	cpu_pfr			(int);
278129198Scognet
279129198Scognet#ifdef CPU_ARM3
280129198Scognetu_int	arm3_control		(u_int clear, u_int bic);
281129198Scognetvoid	arm3_cache_flush	(void);
282129198Scognet#endif	/* CPU_ARM3 */
283129198Scognet
284129198Scognet#if defined(CPU_ARM6) || defined(CPU_ARM7)
285129198Scognetvoid	arm67_setttb		(u_int ttb);
286129198Scognetvoid	arm67_tlb_flush		(void);
287129198Scognetvoid	arm67_tlb_purge		(u_int va);
288129198Scognetvoid	arm67_cache_flush	(void);
289129198Scognetvoid	arm67_context_switch	(void);
290129198Scognet#endif	/* CPU_ARM6 || CPU_ARM7 */
291129198Scognet
292129198Scognet#ifdef CPU_ARM6
293129198Scognetvoid	arm6_setup		(char *string);
294129198Scognet#endif	/* CPU_ARM6 */
295129198Scognet
296129198Scognet#ifdef CPU_ARM7
297129198Scognetvoid	arm7_setup		(char *string);
298129198Scognet#endif	/* CPU_ARM7 */
299129198Scognet
300129198Scognet#ifdef CPU_ARM7TDMI
301129198Scognetint	arm7_dataabt_fixup	(void *arg);
302129198Scognetvoid	arm7tdmi_setup		(char *string);
303129198Scognetvoid	arm7tdmi_setttb		(u_int ttb);
304129198Scognetvoid	arm7tdmi_tlb_flushID	(void);
305129198Scognetvoid	arm7tdmi_tlb_flushID_SE	(u_int va);
306129198Scognetvoid	arm7tdmi_cache_flushID	(void);
307129198Scognetvoid	arm7tdmi_context_switch	(void);
308129198Scognet#endif /* CPU_ARM7TDMI */
309129198Scognet
310129198Scognet#ifdef CPU_ARM8
311129198Scognetvoid	arm8_setttb		(u_int ttb);
312129198Scognetvoid	arm8_tlb_flushID	(void);
313129198Scognetvoid	arm8_tlb_flushID_SE	(u_int va);
314129198Scognetvoid	arm8_cache_flushID	(void);
315129198Scognetvoid	arm8_cache_flushID_E	(u_int entry);
316129198Scognetvoid	arm8_cache_cleanID	(void);
317129198Scognetvoid	arm8_cache_cleanID_E	(u_int entry);
318129198Scognetvoid	arm8_cache_purgeID	(void);
319129198Scognetvoid	arm8_cache_purgeID_E	(u_int entry);
320129198Scognet
321129198Scognetvoid	arm8_cache_syncI	(void);
322129198Scognetvoid	arm8_cache_cleanID_rng	(vm_offset_t start, vm_size_t end);
323129198Scognetvoid	arm8_cache_cleanD_rng	(vm_offset_t start, vm_size_t end);
324129198Scognetvoid	arm8_cache_purgeID_rng	(vm_offset_t start, vm_size_t end);
325129198Scognetvoid	arm8_cache_purgeD_rng	(vm_offset_t start, vm_size_t end);
326129198Scognetvoid	arm8_cache_syncI_rng	(vm_offset_t start, vm_size_t end);
327129198Scognet
328129198Scognetvoid	arm8_context_switch	(void);
329129198Scognet
330129198Scognetvoid	arm8_setup		(char *string);
331129198Scognet
332129198Scognetu_int	arm8_clock_config	(u_int, u_int);
333129198Scognet#endif
334129198Scognet
335201468Srpaulo
336207611Skevlo#if defined(CPU_FA526) || defined(CPU_FA626TE)
337201468Srpaulovoid	fa526_setup		(char *arg);
338201468Srpaulovoid	fa526_setttb		(u_int ttb);
339201468Srpaulovoid	fa526_context_switch	(void);
340201468Srpaulovoid	fa526_cpu_sleep		(int);
341201468Srpaulovoid	fa526_tlb_flushI_SE	(u_int);
342201468Srpaulovoid	fa526_tlb_flushID_SE	(u_int);
343201468Srpaulovoid	fa526_flush_prefetchbuf	(void);
344201468Srpaulovoid	fa526_flush_brnchtgt_E	(u_int);
345201468Srpaulo
346201468Srpaulovoid	fa526_icache_sync_all	(void);
347201468Srpaulovoid	fa526_icache_sync_range(vm_offset_t start, vm_size_t end);
348201468Srpaulovoid	fa526_dcache_wbinv_all	(void);
349201468Srpaulovoid	fa526_dcache_wbinv_range(vm_offset_t start, vm_size_t end);
350201468Srpaulovoid	fa526_dcache_inv_range	(vm_offset_t start, vm_size_t end);
351201468Srpaulovoid	fa526_dcache_wb_range	(vm_offset_t start, vm_size_t end);
352201468Srpaulovoid	fa526_idcache_wbinv_all(void);
353201468Srpaulovoid	fa526_idcache_wbinv_range(vm_offset_t start, vm_size_t end);
354201468Srpaulo#endif
355201468Srpaulo
356201468Srpaulo
357129198Scognet#ifdef CPU_SA110
358129198Scognetvoid	sa110_setup		(char *string);
359129198Scognetvoid	sa110_context_switch	(void);
360129198Scognet#endif	/* CPU_SA110 */
361129198Scognet
362129198Scognet#if defined(CPU_SA1100) || defined(CPU_SA1110)
363129198Scognetvoid	sa11x0_drain_readbuf	(void);
364129198Scognet
365129198Scognetvoid	sa11x0_context_switch	(void);
366129198Scognetvoid	sa11x0_cpu_sleep	(int mode);
367236992Simp
368129198Scognetvoid	sa11x0_setup		(char *string);
369129198Scognet#endif
370129198Scognet
371129198Scognet#if defined(CPU_SA110) || defined(CPU_SA1100) || defined(CPU_SA1110)
372129198Scognetvoid	sa1_setttb		(u_int ttb);
373129198Scognet
374129198Scognetvoid	sa1_tlb_flushID_SE	(u_int va);
375129198Scognet
376129198Scognetvoid	sa1_cache_flushID	(void);
377129198Scognetvoid	sa1_cache_flushI	(void);
378129198Scognetvoid	sa1_cache_flushD	(void);
379129198Scognetvoid	sa1_cache_flushD_SE	(u_int entry);
380129198Scognet
381129198Scognetvoid	sa1_cache_cleanID	(void);
382129198Scognetvoid	sa1_cache_cleanD	(void);
383129198Scognetvoid	sa1_cache_cleanD_E	(u_int entry);
384129198Scognet
385129198Scognetvoid	sa1_cache_purgeID	(void);
386129198Scognetvoid	sa1_cache_purgeID_E	(u_int entry);
387129198Scognetvoid	sa1_cache_purgeD	(void);
388129198Scognetvoid	sa1_cache_purgeD_E	(u_int entry);
389129198Scognet
390129198Scognetvoid	sa1_cache_syncI		(void);
391129198Scognetvoid	sa1_cache_cleanID_rng	(vm_offset_t start, vm_size_t end);
392129198Scognetvoid	sa1_cache_cleanD_rng	(vm_offset_t start, vm_size_t end);
393129198Scognetvoid	sa1_cache_purgeID_rng	(vm_offset_t start, vm_size_t end);
394129198Scognetvoid	sa1_cache_purgeD_rng	(vm_offset_t start, vm_size_t end);
395129198Scognetvoid	sa1_cache_syncI_rng	(vm_offset_t start, vm_size_t end);
396129198Scognet
397129198Scognet#endif
398129198Scognet
399129198Scognet#ifdef CPU_ARM9
400129198Scognetvoid	arm9_setttb		(u_int);
401129198Scognet
402129198Scognetvoid	arm9_tlb_flushID_SE	(u_int va);
403129198Scognet
404167752Skevlovoid	arm9_icache_sync_all	(void);
405167752Skevlovoid	arm9_icache_sync_range	(vm_offset_t, vm_size_t);
406129198Scognet
407167752Skevlovoid	arm9_dcache_wbinv_all	(void);
408167752Skevlovoid	arm9_dcache_wbinv_range (vm_offset_t, vm_size_t);
409167752Skevlovoid	arm9_dcache_inv_range	(vm_offset_t, vm_size_t);
410167752Skevlovoid	arm9_dcache_wb_range	(vm_offset_t, vm_size_t);
411129198Scognet
412167752Skevlovoid	arm9_idcache_wbinv_all	(void);
413167752Skevlovoid	arm9_idcache_wbinv_range (vm_offset_t, vm_size_t);
414129198Scognet
415129198Scognetvoid	arm9_context_switch	(void);
416129198Scognet
417129198Scognetvoid	arm9_setup		(char *string);
418146948Scognet
419146948Scognetextern unsigned arm9_dcache_sets_max;
420146948Scognetextern unsigned arm9_dcache_sets_inc;
421146948Scognetextern unsigned arm9_dcache_index_max;
422146948Scognetextern unsigned arm9_dcache_index_inc;
423129198Scognet#endif
424129198Scognet
425172738Simp#if defined(CPU_ARM9E) || defined(CPU_ARM10)
426129198Scognetvoid	arm10_setttb		(u_int);
427129198Scognet
428129198Scognetvoid	arm10_tlb_flushID_SE	(u_int);
429129198Scognetvoid	arm10_tlb_flushI_SE	(u_int);
430129198Scognet
431129198Scognetvoid	arm10_icache_sync_all	(void);
432129198Scognetvoid	arm10_icache_sync_range	(vm_offset_t, vm_size_t);
433129198Scognet
434129198Scognetvoid	arm10_dcache_wbinv_all	(void);
435129198Scognetvoid	arm10_dcache_wbinv_range (vm_offset_t, vm_size_t);
436129198Scognetvoid	arm10_dcache_inv_range	(vm_offset_t, vm_size_t);
437129198Scognetvoid	arm10_dcache_wb_range	(vm_offset_t, vm_size_t);
438129198Scognet
439129198Scognetvoid	arm10_idcache_wbinv_all	(void);
440129198Scognetvoid	arm10_idcache_wbinv_range (vm_offset_t, vm_size_t);
441129198Scognet
442129198Scognetvoid	arm10_context_switch	(void);
443129198Scognet
444129198Scognetvoid	arm10_setup		(char *string);
445129198Scognet
446129198Scognetextern unsigned arm10_dcache_sets_max;
447129198Scognetextern unsigned arm10_dcache_sets_inc;
448129198Scognetextern unsigned arm10_dcache_index_max;
449129198Scognetextern unsigned arm10_dcache_index_inc;
450183835Sraj
451186933Sraju_int	sheeva_control_ext 		(u_int, u_int);
452212825Smavvoid	sheeva_cpu_sleep		(int);
453186933Srajvoid	sheeva_setttb			(u_int);
454186933Srajvoid	sheeva_dcache_wbinv_range	(vm_offset_t, vm_size_t);
455186933Srajvoid	sheeva_dcache_inv_range		(vm_offset_t, vm_size_t);
456186933Srajvoid	sheeva_dcache_wb_range		(vm_offset_t, vm_size_t);
457186933Srajvoid	sheeva_idcache_wbinv_range	(vm_offset_t, vm_size_t);
458183835Sraj
459186933Srajvoid	sheeva_l2cache_wbinv_range	(vm_offset_t, vm_size_t);
460186933Srajvoid	sheeva_l2cache_inv_range	(vm_offset_t, vm_size_t);
461186933Srajvoid	sheeva_l2cache_wb_range		(vm_offset_t, vm_size_t);
462186933Srajvoid	sheeva_l2cache_wbinv_all	(void);
463129198Scognet#endif
464129198Scognet
465244480Sgonzo#if defined(CPU_ARM1136) || defined(CPU_ARM1176) || \
466244480Sgonzo	defined(CPU_MV_PJ4B) || defined(CPU_CORTEXA)
467172738Simpvoid	arm11_setttb		(u_int);
468239268Sgonzovoid	arm11_sleep		(int);
469172738Simp
470172738Simpvoid	arm11_tlb_flushID_SE	(u_int);
471172738Simpvoid	arm11_tlb_flushI_SE	(u_int);
472172738Simp
473172738Simpvoid	arm11_context_switch	(void);
474172738Simp
475172738Simpvoid	arm11_setup		(char *string);
476172738Simpvoid	arm11_tlb_flushID	(void);
477172738Simpvoid	arm11_tlb_flushI	(void);
478172738Simpvoid	arm11_tlb_flushD	(void);
479172738Simpvoid	arm11_tlb_flushD_SE	(u_int va);
480172738Simp
481172738Simpvoid	arm11_drain_writebuf	(void);
482239268Sgonzo
483239268Sgonzovoid	pj4b_setttb			(u_int);
484239268Sgonzo
485239268Sgonzovoid	pj4b_icache_sync_range		(vm_offset_t, vm_size_t);
486239268Sgonzo
487239268Sgonzovoid	pj4b_dcache_wbinv_range		(vm_offset_t, vm_size_t);
488239268Sgonzovoid	pj4b_dcache_inv_range		(vm_offset_t, vm_size_t);
489239268Sgonzovoid	pj4b_dcache_wb_range		(vm_offset_t, vm_size_t);
490239268Sgonzo
491239268Sgonzovoid	pj4b_idcache_wbinv_range	(vm_offset_t, vm_size_t);
492239268Sgonzo
493239268Sgonzovoid	pj4b_drain_readbuf		(void);
494239268Sgonzovoid	pj4b_flush_brnchtgt_all		(void);
495239268Sgonzovoid	pj4b_flush_brnchtgt_va		(u_int);
496239268Sgonzovoid	pj4b_sleep			(int);
497239268Sgonzo
498239268Sgonzovoid	armv6_icache_sync_all		(void);
499239701Sgonzovoid	armv6_icache_sync_range		(vm_offset_t, vm_size_t);
500239701Sgonzo
501239268Sgonzovoid	armv6_dcache_wbinv_all		(void);
502239701Sgonzovoid	armv6_dcache_wbinv_range	(vm_offset_t, vm_size_t);
503239701Sgonzovoid	armv6_dcache_inv_range		(vm_offset_t, vm_size_t);
504239701Sgonzovoid	armv6_dcache_wb_range		(vm_offset_t, vm_size_t);
505239701Sgonzo
506239268Sgonzovoid	armv6_idcache_wbinv_all		(void);
507239701Sgonzovoid	armv6_idcache_wbinv_range	(vm_offset_t, vm_size_t);
508239268Sgonzo
509239268Sgonzovoid	armv7_setttb			(u_int);
510239268Sgonzovoid	armv7_tlb_flushID		(void);
511239268Sgonzovoid	armv7_tlb_flushID_SE		(u_int);
512239268Sgonzovoid	armv7_icache_sync_range		(vm_offset_t, vm_size_t);
513239268Sgonzovoid	armv7_idcache_wbinv_range	(vm_offset_t, vm_size_t);
514239268Sgonzovoid	armv7_dcache_wbinv_all		(void);
515239268Sgonzovoid	armv7_idcache_wbinv_all		(void);
516239268Sgonzovoid	armv7_dcache_wbinv_range	(vm_offset_t, vm_size_t);
517239268Sgonzovoid	armv7_dcache_inv_range		(vm_offset_t, vm_size_t);
518239268Sgonzovoid	armv7_dcache_wb_range		(vm_offset_t, vm_size_t);
519239268Sgonzovoid	armv7_cpu_sleep			(int);
520239268Sgonzovoid	armv7_setup			(char *string);
521239268Sgonzovoid	armv7_context_switch		(void);
522239268Sgonzovoid	armv7_drain_writebuf		(void);
523239268Sgonzovoid	armv7_sev			(void);
524239268Sgonzou_int	armv7_auxctrl			(u_int, u_int);
525239268Sgonzovoid	pj4bv7_setup			(char *string);
526239268Sgonzovoid	pj4bv6_setup			(char *string);
527239268Sgonzovoid	pj4b_config			(void);
528239268Sgonzo
529239268Sgonzoint	get_core_id			(void);
530239268Sgonzo
531239268Sgonzovoid	armadaxp_idcache_wbinv_all	(void);
532239268Sgonzo
533239268Sgonzovoid 	cortexa_setup			(char *);
534172738Simp#endif
535172738Simp
536244480Sgonzo#if defined(CPU_ARM1136) || defined(CPU_ARM1176)
537244480Sgonzovoid    arm11x6_setttb                  (u_int);
538244480Sgonzovoid    arm11x6_idcache_wbinv_all       (void);
539244480Sgonzovoid    arm11x6_dcache_wbinv_all        (void);
540244480Sgonzovoid    arm11x6_icache_sync_all         (void);
541244480Sgonzovoid    arm11x6_flush_prefetchbuf       (void);
542244480Sgonzovoid    arm11x6_icache_sync_range       (vm_offset_t, vm_size_t);
543244480Sgonzovoid    arm11x6_idcache_wbinv_range     (vm_offset_t, vm_size_t);
544244480Sgonzovoid    arm11x6_setup                   (char *string);
545244480Sgonzovoid    arm11x6_sleep                   (int);  /* no ref. for errata */
546244480Sgonzo#endif
547244480Sgonzo#if defined(CPU_ARM1136)
548244480Sgonzovoid    arm1136_sleep_rev0              (int);  /* for errata 336501 */
549244480Sgonzo#endif
550244480Sgonzo
551172738Simp#if defined(CPU_ARM9E) || defined (CPU_ARM10)
552172738Simpvoid	armv5_ec_setttb(u_int);
553172738Simp
554172738Simpvoid	armv5_ec_icache_sync_all(void);
555172738Simpvoid	armv5_ec_icache_sync_range(vm_offset_t, vm_size_t);
556172738Simp
557172738Simpvoid	armv5_ec_dcache_wbinv_all(void);
558172738Simpvoid	armv5_ec_dcache_wbinv_range(vm_offset_t, vm_size_t);
559172738Simpvoid	armv5_ec_dcache_inv_range(vm_offset_t, vm_size_t);
560172738Simpvoid	armv5_ec_dcache_wb_range(vm_offset_t, vm_size_t);
561172738Simp
562172738Simpvoid	armv5_ec_idcache_wbinv_all(void);
563172738Simpvoid	armv5_ec_idcache_wbinv_range(vm_offset_t, vm_size_t);
564172738Simp#endif
565172738Simp
566239268Sgonzo#if defined (CPU_ARM10)
567172738Simpvoid	armv5_setttb(u_int);
568172738Simp
569172738Simpvoid	armv5_icache_sync_all(void);
570172738Simpvoid	armv5_icache_sync_range(vm_offset_t, vm_size_t);
571172738Simp
572172738Simpvoid	armv5_dcache_wbinv_all(void);
573172738Simpvoid	armv5_dcache_wbinv_range(vm_offset_t, vm_size_t);
574172738Simpvoid	armv5_dcache_inv_range(vm_offset_t, vm_size_t);
575172738Simpvoid	armv5_dcache_wb_range(vm_offset_t, vm_size_t);
576172738Simp
577172738Simpvoid	armv5_idcache_wbinv_all(void);
578172738Simpvoid	armv5_idcache_wbinv_range(vm_offset_t, vm_size_t);
579172738Simp
580172738Simpextern unsigned armv5_dcache_sets_max;
581172738Simpextern unsigned armv5_dcache_sets_inc;
582172738Simpextern unsigned armv5_dcache_index_max;
583172738Simpextern unsigned armv5_dcache_index_inc;
584172738Simp#endif
585172738Simp
586207611Skevlo#if defined(CPU_ARM9) || defined(CPU_ARM9E) || defined(CPU_ARM10) ||	\
587207611Skevlo  defined(CPU_SA110) || defined(CPU_SA1100) || defined(CPU_SA1110) ||	\
588207611Skevlo  defined(CPU_XSCALE_80200) || defined(CPU_XSCALE_80321) ||		\
589207611Skevlo  defined(CPU_FA526) || defined(CPU_FA626TE) ||				\
590207611Skevlo  defined(CPU_XSCALE_PXA2X0) || defined(CPU_XSCALE_IXP425) ||		\
591164080Scognet  defined(CPU_XSCALE_80219) || defined(CPU_XSCALE_81342)
592236992Simp
593129198Scognetvoid	armv4_tlb_flushID	(void);
594129198Scognetvoid	armv4_tlb_flushI	(void);
595129198Scognetvoid	armv4_tlb_flushD	(void);
596129198Scognetvoid	armv4_tlb_flushD_SE	(u_int va);
597129198Scognet
598129198Scognetvoid	armv4_drain_writebuf	(void);
599129198Scognet#endif
600129198Scognet
601129198Scognet#if defined(CPU_IXP12X0)
602129198Scognetvoid	ixp12x0_drain_readbuf	(void);
603129198Scognetvoid	ixp12x0_context_switch	(void);
604129198Scognetvoid	ixp12x0_setup		(char *string);
605129198Scognet#endif
606129198Scognet
607161592Scognet#if defined(CPU_XSCALE_80200) || defined(CPU_XSCALE_80321) ||	\
608161592Scognet  defined(CPU_XSCALE_PXA2X0) || defined(CPU_XSCALE_IXP425) ||	\
609164080Scognet  defined(CPU_XSCALE_80219) || defined(CPU_XSCALE_81342)
610129198Scognetvoid	xscale_cpwait		(void);
611129198Scognet
612129198Scognetvoid	xscale_cpu_sleep	(int mode);
613129198Scognet
614129198Scognetu_int	xscale_control		(u_int clear, u_int bic);
615129198Scognet
616129198Scognetvoid	xscale_setttb		(u_int ttb);
617129198Scognet
618129198Scognetvoid	xscale_tlb_flushID_SE	(u_int va);
619129198Scognet
620129198Scognetvoid	xscale_cache_flushID	(void);
621129198Scognetvoid	xscale_cache_flushI	(void);
622129198Scognetvoid	xscale_cache_flushD	(void);
623129198Scognetvoid	xscale_cache_flushD_SE	(u_int entry);
624129198Scognet
625129198Scognetvoid	xscale_cache_cleanID	(void);
626129198Scognetvoid	xscale_cache_cleanD	(void);
627129198Scognetvoid	xscale_cache_cleanD_E	(u_int entry);
628129198Scognet
629129198Scognetvoid	xscale_cache_clean_minidata (void);
630129198Scognet
631129198Scognetvoid	xscale_cache_purgeID	(void);
632129198Scognetvoid	xscale_cache_purgeID_E	(u_int entry);
633129198Scognetvoid	xscale_cache_purgeD	(void);
634129198Scognetvoid	xscale_cache_purgeD_E	(u_int entry);
635129198Scognet
636129198Scognetvoid	xscale_cache_syncI	(void);
637129198Scognetvoid	xscale_cache_cleanID_rng (vm_offset_t start, vm_size_t end);
638129198Scognetvoid	xscale_cache_cleanD_rng	(vm_offset_t start, vm_size_t end);
639129198Scognetvoid	xscale_cache_purgeID_rng (vm_offset_t start, vm_size_t end);
640129198Scognetvoid	xscale_cache_purgeD_rng	(vm_offset_t start, vm_size_t end);
641129198Scognetvoid	xscale_cache_syncI_rng	(vm_offset_t start, vm_size_t end);
642129198Scognetvoid	xscale_cache_flushD_rng	(vm_offset_t start, vm_size_t end);
643129198Scognet
644129198Scognetvoid	xscale_context_switch	(void);
645129198Scognet
646129198Scognetvoid	xscale_setup		(char *string);
647236992Simp#endif	/* CPU_XSCALE_80200 || CPU_XSCALE_80321 || CPU_XSCALE_PXA2X0 || CPU_XSCALE_IXP425
648161592Scognet	   CPU_XSCALE_80219 */
649129198Scognet
650164080Scognet#ifdef	CPU_XSCALE_81342
651164080Scognet
652171618Scognetvoid	xscalec3_l2cache_purge	(void);
653171618Scognetvoid	xscalec3_cache_purgeID	(void);
654171618Scognetvoid	xscalec3_cache_purgeD	(void);
655164080Scognetvoid	xscalec3_cache_cleanID	(void);
656164080Scognetvoid	xscalec3_cache_cleanD	(void);
657171618Scognetvoid	xscalec3_cache_syncI	(void);
658164080Scognet
659171618Scognetvoid	xscalec3_cache_purgeID_rng 	(vm_offset_t start, vm_size_t end);
660171618Scognetvoid	xscalec3_cache_purgeD_rng	(vm_offset_t start, vm_size_t end);
661171618Scognetvoid	xscalec3_cache_cleanID_rng	(vm_offset_t start, vm_size_t end);
662164080Scognetvoid	xscalec3_cache_cleanD_rng	(vm_offset_t start, vm_size_t end);
663171618Scognetvoid	xscalec3_cache_syncI_rng	(vm_offset_t start, vm_size_t end);
664164080Scognet
665171618Scognetvoid	xscalec3_l2cache_flush_rng	(vm_offset_t, vm_size_t);
666171618Scognetvoid	xscalec3_l2cache_clean_rng	(vm_offset_t start, vm_size_t end);
667171618Scognetvoid	xscalec3_l2cache_purge_rng	(vm_offset_t start, vm_size_t end);
668164080Scognet
669171618Scognet
670164080Scognetvoid	xscalec3_setttb		(u_int ttb);
671164080Scognetvoid	xscalec3_context_switch	(void);
672164080Scognet
673164080Scognet#endif /* CPU_XSCALE_81342 */
674164080Scognet
675129198Scognet#define tlb_flush	cpu_tlb_flushID
676129198Scognet#define setttb		cpu_setttb
677129198Scognet#define drain_writebuf	cpu_drain_writebuf
678129198Scognet
679129198Scognet/*
680129198Scognet * Macros for manipulating CPU interrupts
681129198Scognet */
682129198Scognetstatic __inline u_int32_t __set_cpsr_c(u_int bic, u_int eor) __attribute__((__unused__));
683129198Scognet
684129198Scognetstatic __inline u_int32_t
685129198Scognet__set_cpsr_c(u_int bic, u_int eor)
686129198Scognet{
687129198Scognet	u_int32_t	tmp, ret;
688129198Scognet
689129198Scognet	__asm __volatile(
690129198Scognet		"mrs     %0, cpsr\n"	/* Get the CPSR */
691129198Scognet		"bic	 %1, %0, %2\n"	/* Clear bits */
692129198Scognet		"eor	 %1, %1, %3\n"	/* XOR bits */
693129198Scognet		"msr     cpsr_c, %1\n"	/* Set the control field of CPSR */
694129198Scognet	: "=&r" (ret), "=&r" (tmp)
695137226Scognet	: "r" (bic), "r" (eor) : "memory");
696129198Scognet
697129198Scognet	return ret;
698129198Scognet}
699129198Scognet
700243576Smarcel#define	ARM_CPSR_F32	(1 << 6)	/* FIQ disable */
701243576Smarcel#define	ARM_CPSR_I32	(1 << 7)	/* IRQ disable */
702243576Smarcel
703129198Scognet#define disable_interrupts(mask)					\
704243576Smarcel	(__set_cpsr_c((mask) & (ARM_CPSR_I32 | ARM_CPSR_F32),		\
705243576Smarcel		      (mask) & (ARM_CPSR_I32 | ARM_CPSR_F32)))
706129198Scognet
707129198Scognet#define enable_interrupts(mask)						\
708243576Smarcel	(__set_cpsr_c((mask) & (ARM_CPSR_I32 | ARM_CPSR_F32), 0))
709129198Scognet
710129198Scognet#define restore_interrupts(old_cpsr)					\
711243576Smarcel	(__set_cpsr_c((ARM_CPSR_I32 | ARM_CPSR_F32),			\
712243576Smarcel		      (old_cpsr) & (ARM_CPSR_I32 | ARM_CPSR_F32)))
713129198Scognet
714243576Smarcelstatic __inline register_t
715243576Smarcelintr_disable(void)
716243576Smarcel{
717243576Smarcel	register_t s;
718243576Smarcel
719243576Smarcel	s = disable_interrupts(ARM_CPSR_I32 | ARM_CPSR_F32);
720243576Smarcel	return (s);
721243576Smarcel}
722243576Smarcel
723243576Smarcelstatic __inline void
724243576Smarcelintr_restore(register_t s)
725243576Smarcel{
726243576Smarcel
727243576Smarcel	restore_interrupts(s);
728243576Smarcel}
729243576Smarcel
730129198Scognet/* Functions to manipulate the CPSR. */
731129198Scognetu_int	SetCPSR(u_int bic, u_int eor);
732129198Scognetu_int	GetCPSR(void);
733129198Scognet
734129198Scognet/*
735129198Scognet * Functions to manipulate cpu r13
736129198Scognet * (in arm/arm32/setstack.S)
737129198Scognet */
738129198Scognet
739167752Skevlovoid set_stackptr	(u_int mode, u_int address);
740167752Skevlou_int get_stackptr	(u_int mode);
741129198Scognet
742129198Scognet/*
743129198Scognet * Miscellany
744129198Scognet */
745129198Scognet
746167752Skevloint get_pc_str_offset	(void);
747129198Scognet
748129198Scognet/*
749129198Scognet * CPU functions from locore.S
750129198Scognet */
751129198Scognet
752167752Skevlovoid cpu_reset		(void) __attribute__((__noreturn__));
753129198Scognet
754129198Scognet/*
755129198Scognet * Cache info variables.
756129198Scognet */
757129198Scognet
758129198Scognet/* PRIMARY CACHE VARIABLES */
759129198Scognetextern int	arm_picache_size;
760129198Scognetextern int	arm_picache_line_size;
761129198Scognetextern int	arm_picache_ways;
762129198Scognet
763129198Scognetextern int	arm_pdcache_size;	/* and unified */
764129198Scognetextern int	arm_pdcache_line_size;
765236992Simpextern int	arm_pdcache_ways;
766129198Scognet
767129198Scognetextern int	arm_pcache_type;
768129198Scognetextern int	arm_pcache_unified;
769129198Scognet
770129198Scognetextern int	arm_dcache_align;
771129198Scognetextern int	arm_dcache_align_mask;
772129198Scognet
773239268Sgonzoextern u_int	arm_cache_level;
774239268Sgonzoextern u_int	arm_cache_loc;
775239268Sgonzoextern u_int	arm_cache_type[14];
776239268Sgonzo
777129198Scognet#endif	/* _KERNEL */
778129198Scognet#endif	/* _MACHINE_CPUFUNC_H_ */
779129198Scognet
780129198Scognet/* End of cpufunc.h */
781