cpufunc.h revision 295096
1323136Sdes/*	$NetBSD: cpufunc.h,v 1.29 2003/09/06 09:08:35 rearnsha Exp $	*/
2276707Sdes
3276707Sdes/*-
4276707Sdes * Copyright (c) 1997 Mark Brinicombe.
5276707Sdes * Copyright (c) 1997 Causality Limited
6276707Sdes * All rights reserved.
7276707Sdes *
8276707Sdes * Redistribution and use in source and binary forms, with or without
9276707Sdes * modification, are permitted provided that the following conditions
10276707Sdes * are met:
11276707Sdes * 1. Redistributions of source code must retain the above copyright
12276707Sdes *    notice, this list of conditions and the following disclaimer.
13276707Sdes * 2. Redistributions in binary form must reproduce the above copyright
14276707Sdes *    notice, this list of conditions and the following disclaimer in the
15276707Sdes *    documentation and/or other materials provided with the distribution.
16276707Sdes * 3. All advertising materials mentioning features or use of this software
17276707Sdes *    must display the following acknowledgement:
18276707Sdes *	This product includes software developed by Causality Limited.
19276707Sdes * 4. The name of Causality Limited may not be used to endorse or promote
20276707Sdes *    products derived from this software without specific prior written
21276707Sdes *    permission.
22276707Sdes *
23276707Sdes * THIS SOFTWARE IS PROVIDED BY CAUSALITY LIMITED ``AS IS'' AND ANY EXPRESS
24276707Sdes * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
25276707Sdes * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
26276707Sdes * DISCLAIMED. IN NO EVENT SHALL CAUSALITY LIMITED BE LIABLE FOR ANY DIRECT,
27276707Sdes * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
28276707Sdes * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
29276707Sdes * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
30276707Sdes * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
31276707Sdes * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
32276707Sdes * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
33276707Sdes * SUCH DAMAGE.
34276707Sdes *
35276707Sdes * RiscBSD kernel project
36276707Sdes *
37276707Sdes * cpufunc.h
38276707Sdes *
39276707Sdes * Prototypes for cpu, mmu and tlb related functions.
40276707Sdes *
41276707Sdes * $FreeBSD: head/sys/arm/include/cpufunc.h 295096 2016-01-31 16:34:06Z mmel $
42276707Sdes */
43276707Sdes
44276707Sdes#ifndef _MACHINE_CPUFUNC_H_
45276707Sdes#define _MACHINE_CPUFUNC_H_
46276707Sdes
47276707Sdes#ifdef _KERNEL
48276707Sdes
49276707Sdes#include <sys/types.h>
50276707Sdes#include <machine/armreg.h>
51276707Sdes#include <machine/cpuconf.h>
52276707Sdes
53276707Sdesstatic __inline void
54276707Sdesbreakpoint(void)
55276707Sdes{
56276707Sdes	__asm(".word      0xe7ffffff");
57276707Sdes}
58276707Sdes
59276707Sdesstruct cpu_functions {
60276707Sdes
61276707Sdes	/* CPU functions */
62276707Sdes
63276707Sdes	void	(*cf_cpwait)		(void);
64276707Sdes
65276707Sdes	/* MMU functions */
66276707Sdes
67276707Sdes	u_int	(*cf_control)		(u_int bic, u_int eor);
68294332Sdes	void	(*cf_setttb)		(u_int ttb);
69294332Sdes
70276707Sdes	/* TLB functions */
71276707Sdes
72276707Sdes	void	(*cf_tlb_flushID)	(void);
73294332Sdes	void	(*cf_tlb_flushID_SE)	(u_int va);
74276707Sdes	void	(*cf_tlb_flushI)	(void);
75294332Sdes	void	(*cf_tlb_flushI_SE)	(u_int va);
76276707Sdes	void	(*cf_tlb_flushD)	(void);
77276707Sdes	void	(*cf_tlb_flushD_SE)	(u_int va);
78276707Sdes
79276707Sdes	/*
80276707Sdes	 * Cache operations:
81276707Sdes	 *
82276707Sdes	 * We define the following primitives:
83276707Sdes	 *
84276707Sdes	 *	icache_sync_all		Synchronize I-cache
85276707Sdes	 *	icache_sync_range	Synchronize I-cache range
86276707Sdes	 *
87276707Sdes	 *	dcache_wbinv_all	Write-back and Invalidate D-cache
88276707Sdes	 *	dcache_wbinv_range	Write-back and Invalidate D-cache range
89276707Sdes	 *	dcache_inv_range	Invalidate D-cache range
90276707Sdes	 *	dcache_wb_range		Write-back D-cache range
91276707Sdes	 *
92276707Sdes	 *	idcache_wbinv_all	Write-back and Invalidate D-cache,
93276707Sdes	 *				Invalidate I-cache
94276707Sdes	 *	idcache_wbinv_range	Write-back and Invalidate D-cache,
95276707Sdes	 *				Invalidate I-cache range
96276707Sdes	 *
97276707Sdes	 * Note that the ARM term for "write-back" is "clean".  We use
98276707Sdes	 * the term "write-back" since it's a more common way to describe
99276707Sdes	 * the operation.
100276707Sdes	 *
101276707Sdes	 * There are some rules that must be followed:
102276707Sdes	 *
103276707Sdes	 *	ID-cache Invalidate All:
104276707Sdes	 *		Unlike other functions, this one must never write back.
105276707Sdes	 *		It is used to intialize the MMU when it is in an unknown
106276707Sdes	 *		state (such as when it may have lines tagged as valid
107276707Sdes	 *		that belong to a previous set of mappings).
108276707Sdes	 *
109276707Sdes	 *	I-cache Synch (all or range):
110276707Sdes	 *		The goal is to synchronize the instruction stream,
111276707Sdes	 *		so you may beed to write-back dirty D-cache blocks
112276707Sdes	 *		first.  If a range is requested, and you can't
113276707Sdes	 *		synchronize just a range, you have to hit the whole
114276707Sdes	 *		thing.
115276707Sdes	 *
116276707Sdes	 *	D-cache Write-Back and Invalidate range:
117276707Sdes	 *		If you can't WB-Inv a range, you must WB-Inv the
118276707Sdes	 *		entire D-cache.
119276707Sdes	 *
120276707Sdes	 *	D-cache Invalidate:
121276707Sdes	 *		If you can't Inv the D-cache, you must Write-Back
122276707Sdes	 *		and Invalidate.  Code that uses this operation
123294332Sdes	 *		MUST NOT assume that the D-cache will not be written
124276707Sdes	 *		back to memory.
125294332Sdes	 *
126276707Sdes	 *	D-cache Write-Back:
127276707Sdes	 *		If you can't Write-back without doing an Inv,
128276707Sdes	 *		that's fine.  Then treat this as a WB-Inv.
129276707Sdes	 *		Skipping the invalidate is merely an optimization.
130276707Sdes	 *
131276707Sdes	 *	All operations:
132276707Sdes	 *		Valid virtual addresses must be passed to each
133276707Sdes	 *		cache operation.
134276707Sdes	 */
135276707Sdes	void	(*cf_icache_sync_all)	(void);
136276707Sdes	void	(*cf_icache_sync_range)	(vm_offset_t, vm_size_t);
137276707Sdes
138294464Sdes	void	(*cf_dcache_wbinv_all)	(void);
139276707Sdes	void	(*cf_dcache_wbinv_range) (vm_offset_t, vm_size_t);
140323129Sdes	void	(*cf_dcache_inv_range)	(vm_offset_t, vm_size_t);
141276707Sdes	void	(*cf_dcache_wb_range)	(vm_offset_t, vm_size_t);
142276707Sdes
143276707Sdes	void	(*cf_idcache_inv_all)	(void);
144296633Sdes	void	(*cf_idcache_wbinv_all)	(void);
145296633Sdes	void	(*cf_idcache_wbinv_range) (vm_offset_t, vm_size_t);
146276707Sdes	void	(*cf_l2cache_wbinv_all) (void);
147276707Sdes	void	(*cf_l2cache_wbinv_range) (vm_offset_t, vm_size_t);
148276707Sdes	void	(*cf_l2cache_inv_range)	  (vm_offset_t, vm_size_t);
149276707Sdes	void	(*cf_l2cache_wb_range)	  (vm_offset_t, vm_size_t);
150276707Sdes	void	(*cf_l2cache_drain_writebuf)	  (void);
151276707Sdes
152276707Sdes	/* Other functions */
153276707Sdes
154276707Sdes	void	(*cf_flush_prefetchbuf)	(void);
155276707Sdes	void	(*cf_drain_writebuf)	(void);
156276707Sdes
157276707Sdes	void	(*cf_sleep)		(int mode);
158294332Sdes
159323136Sdes	/* Soft functions */
160276707Sdes
161276707Sdes	void	(*cf_context_switch)	(void);
162294332Sdes
163294332Sdes	void	(*cf_setup)		(void);
164276707Sdes};
165294336Sdes
166294332Sdesextern struct cpu_functions cpufuncs;
167294332Sdesextern u_int cputype;
168276707Sdes
169294332Sdes#define	cpu_cpwait()		cpufuncs.cf_cpwait()
170276707Sdes
171276707Sdes#define cpu_control(c, e)	cpufuncs.cf_control(c, e)
172296633Sdes#define cpu_setttb(t)		cpufuncs.cf_setttb(t)
173276707Sdes
174276707Sdes#define	cpu_tlb_flushID()	cpufuncs.cf_tlb_flushID()
175276707Sdes#define	cpu_tlb_flushID_SE(e)	cpufuncs.cf_tlb_flushID_SE(e)
176276707Sdes#define	cpu_tlb_flushI()	cpufuncs.cf_tlb_flushI()
177276707Sdes#define	cpu_tlb_flushI_SE(e)	cpufuncs.cf_tlb_flushI_SE(e)
178276707Sdes#define	cpu_tlb_flushD()	cpufuncs.cf_tlb_flushD()
179276707Sdes#define	cpu_tlb_flushD_SE(e)	cpufuncs.cf_tlb_flushD_SE(e)
180276707Sdes
181276707Sdes#define	cpu_icache_sync_all()	cpufuncs.cf_icache_sync_all()
182276707Sdes#define	cpu_icache_sync_range(a, s) cpufuncs.cf_icache_sync_range((a), (s))
183276707Sdes
184276707Sdes#define	cpu_dcache_wbinv_all()	cpufuncs.cf_dcache_wbinv_all()
185276707Sdes#define	cpu_dcache_wbinv_range(a, s) cpufuncs.cf_dcache_wbinv_range((a), (s))
186276707Sdes#define	cpu_dcache_inv_range(a, s) cpufuncs.cf_dcache_inv_range((a), (s))
187276707Sdes#define	cpu_dcache_wb_range(a, s) cpufuncs.cf_dcache_wb_range((a), (s))
188276707Sdes
189276707Sdes#define	cpu_idcache_inv_all()	cpufuncs.cf_idcache_inv_all()
190276707Sdes#define	cpu_idcache_wbinv_all()	cpufuncs.cf_idcache_wbinv_all()
191296633Sdes#define	cpu_idcache_wbinv_range(a, s) cpufuncs.cf_idcache_wbinv_range((a), (s))
192276707Sdes#define cpu_l2cache_wbinv_all()	cpufuncs.cf_l2cache_wbinv_all()
193276707Sdes#define cpu_l2cache_wb_range(a, s) cpufuncs.cf_l2cache_wb_range((a), (s))
194276707Sdes#define cpu_l2cache_inv_range(a, s) cpufuncs.cf_l2cache_inv_range((a), (s))
195276707Sdes#define cpu_l2cache_wbinv_range(a, s) cpufuncs.cf_l2cache_wbinv_range((a), (s))
196296633Sdes#define cpu_l2cache_drain_writebuf() cpufuncs.cf_l2cache_drain_writebuf()
197296633Sdes
198296633Sdes#define	cpu_flush_prefetchbuf()	cpufuncs.cf_flush_prefetchbuf()
199276707Sdes#define	cpu_drain_writebuf()	cpufuncs.cf_drain_writebuf()
200296633Sdes#define cpu_sleep(m)		cpufuncs.cf_sleep(m)
201276707Sdes
202276707Sdes#define cpu_setup()			cpufuncs.cf_setup()
203276707Sdes
204276707Sdesint	set_cpufuncs		(void);
205276707Sdes#define ARCHITECTURE_NOT_PRESENT	1	/* known but not configured */
206276707Sdes#define ARCHITECTURE_NOT_SUPPORTED	2	/* not known */
207276707Sdes
208276707Sdesvoid	cpufunc_nullop		(void);
209276707Sdesu_int	cpu_ident		(void);
210276707Sdesu_int	cpufunc_control		(u_int clear, u_int bic);
211276707Sdesvoid	cpu_domains		(u_int domains);
212276707Sdesu_int	cpu_faultstatus		(void);
213276707Sdesu_int	cpu_faultaddress	(void);
214276707Sdesu_int	cpu_pfr			(int);
215276707Sdes
216276707Sdes#if defined(CPU_FA526)
217276707Sdesvoid	fa526_setup		(void);
218276707Sdesvoid	fa526_setttb		(u_int ttb);
219276707Sdesvoid	fa526_context_switch	(void);
220276707Sdesvoid	fa526_cpu_sleep		(int);
221276707Sdesvoid	fa526_tlb_flushI_SE	(u_int);
222276707Sdesvoid	fa526_tlb_flushID_SE	(u_int);
223276707Sdesvoid	fa526_flush_prefetchbuf	(void);
224276707Sdes
225276707Sdesvoid	fa526_icache_sync_all	(void);
226276707Sdesvoid	fa526_icache_sync_range(vm_offset_t start, vm_size_t end);
227276707Sdesvoid	fa526_dcache_wbinv_all	(void);
228276707Sdesvoid	fa526_dcache_wbinv_range(vm_offset_t start, vm_size_t end);
229276707Sdesvoid	fa526_dcache_inv_range	(vm_offset_t start, vm_size_t end);
230276707Sdesvoid	fa526_dcache_wb_range	(vm_offset_t start, vm_size_t end);
231void	fa526_idcache_wbinv_all(void);
232void	fa526_idcache_wbinv_range(vm_offset_t start, vm_size_t end);
233#endif
234
235
236#ifdef CPU_ARM9
237void	arm9_setttb		(u_int);
238
239void	arm9_tlb_flushID_SE	(u_int va);
240
241void	arm9_icache_sync_all	(void);
242void	arm9_icache_sync_range	(vm_offset_t, vm_size_t);
243
244void	arm9_dcache_wbinv_all	(void);
245void	arm9_dcache_wbinv_range (vm_offset_t, vm_size_t);
246void	arm9_dcache_inv_range	(vm_offset_t, vm_size_t);
247void	arm9_dcache_wb_range	(vm_offset_t, vm_size_t);
248
249void	arm9_idcache_wbinv_all	(void);
250void	arm9_idcache_wbinv_range (vm_offset_t, vm_size_t);
251
252void	arm9_context_switch	(void);
253
254void	arm9_setup		(void);
255
256extern unsigned arm9_dcache_sets_max;
257extern unsigned arm9_dcache_sets_inc;
258extern unsigned arm9_dcache_index_max;
259extern unsigned arm9_dcache_index_inc;
260#endif
261
262#if defined(CPU_ARM9E)
263void	arm10_tlb_flushID_SE	(u_int);
264void	arm10_tlb_flushI_SE	(u_int);
265
266void	arm10_context_switch	(void);
267
268void	arm10_setup		(void);
269
270u_int	sheeva_control_ext 		(u_int, u_int);
271void	sheeva_cpu_sleep		(int);
272void	sheeva_setttb			(u_int);
273void	sheeva_dcache_wbinv_range	(vm_offset_t, vm_size_t);
274void	sheeva_dcache_inv_range		(vm_offset_t, vm_size_t);
275void	sheeva_dcache_wb_range		(vm_offset_t, vm_size_t);
276void	sheeva_idcache_wbinv_range	(vm_offset_t, vm_size_t);
277
278void	sheeva_l2cache_wbinv_range	(vm_offset_t, vm_size_t);
279void	sheeva_l2cache_inv_range	(vm_offset_t, vm_size_t);
280void	sheeva_l2cache_wb_range		(vm_offset_t, vm_size_t);
281void	sheeva_l2cache_wbinv_all	(void);
282#endif
283
284#if defined(CPU_MV_PJ4B)
285void	armv6_idcache_wbinv_all		(void);
286#endif
287#if defined(CPU_MV_PJ4B) || defined(CPU_CORTEXA) || defined(CPU_KRAIT)
288void	armv7_setttb			(u_int);
289void	armv7_tlb_flushID		(void);
290void	armv7_tlb_flushID_SE		(u_int);
291void	armv7_icache_sync_all		(void);
292void	armv7_icache_sync_range		(vm_offset_t, vm_size_t);
293void	armv7_idcache_wbinv_range	(vm_offset_t, vm_size_t);
294void	armv7_idcache_inv_all		(void);
295void	armv7_dcache_wbinv_all		(void);
296void	armv7_idcache_wbinv_all		(void);
297void	armv7_dcache_wbinv_range	(vm_offset_t, vm_size_t);
298void	armv7_dcache_inv_range		(vm_offset_t, vm_size_t);
299void	armv7_dcache_wb_range		(vm_offset_t, vm_size_t);
300void	armv7_cpu_sleep			(int);
301void	armv7_setup			(void);
302void	armv7_context_switch		(void);
303void	armv7_drain_writebuf		(void);
304void	armv7_sev			(void);
305u_int	armv7_auxctrl			(u_int, u_int);
306
307void	armadaxp_idcache_wbinv_all	(void);
308
309void 	cortexa_setup			(void);
310#endif
311#if defined(CPU_MV_PJ4B)
312void	pj4b_config			(void);
313void	pj4bv7_setup			(void);
314#endif
315
316#if defined(CPU_ARM1176)
317void	arm11_tlb_flushID	(void);
318void	arm11_tlb_flushID_SE	(u_int);
319void	arm11_tlb_flushI	(void);
320void	arm11_tlb_flushI_SE	(u_int);
321void	arm11_tlb_flushD	(void);
322void	arm11_tlb_flushD_SE	(u_int va);
323
324void	arm11_context_switch	(void);
325
326void	arm11_drain_writebuf	(void);
327
328void	armv6_dcache_wbinv_range	(vm_offset_t, vm_size_t);
329void	armv6_dcache_inv_range		(vm_offset_t, vm_size_t);
330void	armv6_dcache_wb_range		(vm_offset_t, vm_size_t);
331
332void	armv6_idcache_inv_all		(void);
333
334void    arm11x6_setttb                  (u_int);
335void    arm11x6_idcache_wbinv_all       (void);
336void    arm11x6_dcache_wbinv_all        (void);
337void    arm11x6_icache_sync_all         (void);
338void    arm11x6_flush_prefetchbuf       (void);
339void    arm11x6_icache_sync_range       (vm_offset_t, vm_size_t);
340void    arm11x6_idcache_wbinv_range     (vm_offset_t, vm_size_t);
341void    arm11x6_setup                   (void);
342void    arm11x6_sleep                   (int);  /* no ref. for errata */
343#endif
344
345#if defined(CPU_ARM9E)
346void	armv5_ec_setttb(u_int);
347
348void	armv5_ec_icache_sync_all(void);
349void	armv5_ec_icache_sync_range(vm_offset_t, vm_size_t);
350
351void	armv5_ec_dcache_wbinv_all(void);
352void	armv5_ec_dcache_wbinv_range(vm_offset_t, vm_size_t);
353void	armv5_ec_dcache_inv_range(vm_offset_t, vm_size_t);
354void	armv5_ec_dcache_wb_range(vm_offset_t, vm_size_t);
355
356void	armv5_ec_idcache_wbinv_all(void);
357void	armv5_ec_idcache_wbinv_range(vm_offset_t, vm_size_t);
358#endif
359
360#if defined(CPU_ARM9) || defined(CPU_ARM9E) ||				\
361  defined(CPU_XSCALE_80321) ||						\
362  defined(CPU_FA526) ||							\
363  defined(CPU_XSCALE_PXA2X0) || defined(CPU_XSCALE_IXP425) ||		\
364  defined(CPU_XSCALE_80219) || defined(CPU_XSCALE_81342)
365
366void	armv4_tlb_flushID	(void);
367void	armv4_tlb_flushI	(void);
368void	armv4_tlb_flushD	(void);
369void	armv4_tlb_flushD_SE	(u_int va);
370
371void	armv4_drain_writebuf	(void);
372void	armv4_idcache_inv_all	(void);
373#endif
374
375#if defined(CPU_XSCALE_80321) ||				\
376  defined(CPU_XSCALE_PXA2X0) || defined(CPU_XSCALE_IXP425) ||	\
377  defined(CPU_XSCALE_80219) || defined(CPU_XSCALE_81342)
378void	xscale_cpwait		(void);
379
380void	xscale_cpu_sleep	(int mode);
381
382u_int	xscale_control		(u_int clear, u_int bic);
383
384void	xscale_setttb		(u_int ttb);
385
386void	xscale_tlb_flushID_SE	(u_int va);
387
388void	xscale_cache_flushID	(void);
389void	xscale_cache_flushI	(void);
390void	xscale_cache_flushD	(void);
391void	xscale_cache_flushD_SE	(u_int entry);
392
393void	xscale_cache_cleanID	(void);
394void	xscale_cache_cleanD	(void);
395void	xscale_cache_cleanD_E	(u_int entry);
396
397void	xscale_cache_clean_minidata (void);
398
399void	xscale_cache_purgeID	(void);
400void	xscale_cache_purgeID_E	(u_int entry);
401void	xscale_cache_purgeD	(void);
402void	xscale_cache_purgeD_E	(u_int entry);
403
404void	xscale_cache_syncI	(void);
405void	xscale_cache_cleanID_rng (vm_offset_t start, vm_size_t end);
406void	xscale_cache_cleanD_rng	(vm_offset_t start, vm_size_t end);
407void	xscale_cache_purgeID_rng (vm_offset_t start, vm_size_t end);
408void	xscale_cache_purgeD_rng	(vm_offset_t start, vm_size_t end);
409void	xscale_cache_syncI_rng	(vm_offset_t start, vm_size_t end);
410void	xscale_cache_flushD_rng	(vm_offset_t start, vm_size_t end);
411
412void	xscale_context_switch	(void);
413
414void	xscale_setup		(void);
415#endif	/* CPU_XSCALE_80321 || CPU_XSCALE_PXA2X0 || CPU_XSCALE_IXP425
416	   CPU_XSCALE_80219 */
417
418#ifdef	CPU_XSCALE_81342
419
420void	xscalec3_l2cache_purge	(void);
421void	xscalec3_cache_purgeID	(void);
422void	xscalec3_cache_purgeD	(void);
423void	xscalec3_cache_cleanID	(void);
424void	xscalec3_cache_cleanD	(void);
425void	xscalec3_cache_syncI	(void);
426
427void	xscalec3_cache_purgeID_rng 	(vm_offset_t start, vm_size_t end);
428void	xscalec3_cache_purgeD_rng	(vm_offset_t start, vm_size_t end);
429void	xscalec3_cache_cleanID_rng	(vm_offset_t start, vm_size_t end);
430void	xscalec3_cache_cleanD_rng	(vm_offset_t start, vm_size_t end);
431void	xscalec3_cache_syncI_rng	(vm_offset_t start, vm_size_t end);
432
433void	xscalec3_l2cache_flush_rng	(vm_offset_t, vm_size_t);
434void	xscalec3_l2cache_clean_rng	(vm_offset_t start, vm_size_t end);
435void	xscalec3_l2cache_purge_rng	(vm_offset_t start, vm_size_t end);
436
437
438void	xscalec3_setttb		(u_int ttb);
439void	xscalec3_context_switch	(void);
440
441#endif /* CPU_XSCALE_81342 */
442
443#define setttb		cpu_setttb
444#define drain_writebuf	cpu_drain_writebuf
445
446/*
447 * Macros for manipulating CPU interrupts
448 */
449#if __ARM_ARCH < 6
450#define	__ARM_INTR_BITS		(PSR_I | PSR_F)
451#else
452#define	__ARM_INTR_BITS		(PSR_I | PSR_F | PSR_A)
453#endif
454
455static __inline uint32_t
456__set_cpsr(uint32_t bic, uint32_t eor)
457{
458	uint32_t	tmp, ret;
459
460	__asm __volatile(
461		"mrs     %0, cpsr\n"		/* Get the CPSR */
462		"bic	 %1, %0, %2\n"		/* Clear bits */
463		"eor	 %1, %1, %3\n"		/* XOR bits */
464		"msr     cpsr_xc, %1\n"		/* Set the CPSR */
465	: "=&r" (ret), "=&r" (tmp)
466	: "r" (bic), "r" (eor) : "memory");
467
468	return ret;
469}
470
471static __inline uint32_t
472disable_interrupts(uint32_t mask)
473{
474
475	return (__set_cpsr(mask & __ARM_INTR_BITS, mask & __ARM_INTR_BITS));
476}
477
478static __inline uint32_t
479enable_interrupts(uint32_t mask)
480{
481
482	return (__set_cpsr(mask & __ARM_INTR_BITS, 0));
483}
484
485static __inline uint32_t
486restore_interrupts(uint32_t old_cpsr)
487{
488
489	return (__set_cpsr(__ARM_INTR_BITS, old_cpsr & __ARM_INTR_BITS));
490}
491
492static __inline register_t
493intr_disable(void)
494{
495
496	return (disable_interrupts(PSR_I | PSR_F));
497}
498
499static __inline void
500intr_restore(register_t s)
501{
502
503	restore_interrupts(s);
504}
505#undef __ARM_INTR_BITS
506
507/*
508 * Functions to manipulate cpu r13
509 * (in arm/arm32/setstack.S)
510 */
511
512void set_stackptr	(u_int mode, u_int address);
513u_int get_stackptr	(u_int mode);
514
515/*
516 * Miscellany
517 */
518
519int get_pc_str_offset	(void);
520
521/*
522 * CPU functions from locore.S
523 */
524
525void cpu_reset		(void) __attribute__((__noreturn__));
526
527/*
528 * Cache info variables.
529 */
530
531/* PRIMARY CACHE VARIABLES */
532extern int	arm_picache_size;
533extern int	arm_picache_line_size;
534extern int	arm_picache_ways;
535
536extern int	arm_pdcache_size;	/* and unified */
537extern int	arm_pdcache_line_size;
538extern int	arm_pdcache_ways;
539
540extern int	arm_pcache_type;
541extern int	arm_pcache_unified;
542
543extern int	arm_dcache_align;
544extern int	arm_dcache_align_mask;
545
546extern u_int	arm_cache_level;
547extern u_int	arm_cache_loc;
548extern u_int	arm_cache_type[14];
549
550#endif	/* _KERNEL */
551#endif	/* _MACHINE_CPUFUNC_H_ */
552
553/* End of cpufunc.h */
554