cpufunc.c revision 259640
1129198Scognet/*	$NetBSD: cpufunc.c,v 1.65 2003/11/05 12:53:15 scw Exp $	*/
2129198Scognet
3139735Simp/*-
4129198Scognet * arm7tdmi support code Copyright (c) 2001 John Fremlin
5129198Scognet * arm8 support code Copyright (c) 1997 ARM Limited
6129198Scognet * arm8 support code Copyright (c) 1997 Causality Limited
7129198Scognet * arm9 support code Copyright (C) 2001 ARM Ltd
8129198Scognet * Copyright (c) 1997 Mark Brinicombe.
9129198Scognet * Copyright (c) 1997 Causality Limited
10129198Scognet * All rights reserved.
11129198Scognet *
12129198Scognet * Redistribution and use in source and binary forms, with or without
13129198Scognet * modification, are permitted provided that the following conditions
14129198Scognet * are met:
15129198Scognet * 1. Redistributions of source code must retain the above copyright
16129198Scognet *    notice, this list of conditions and the following disclaimer.
17129198Scognet * 2. Redistributions in binary form must reproduce the above copyright
18129198Scognet *    notice, this list of conditions and the following disclaimer in the
19129198Scognet *    documentation and/or other materials provided with the distribution.
20129198Scognet * 3. All advertising materials mentioning features or use of this software
21129198Scognet *    must display the following acknowledgement:
22129198Scognet *	This product includes software developed by Causality Limited.
23129198Scognet * 4. The name of Causality Limited may not be used to endorse or promote
24129198Scognet *    products derived from this software without specific prior written
25129198Scognet *    permission.
26129198Scognet *
27129198Scognet * THIS SOFTWARE IS PROVIDED BY CAUSALITY LIMITED ``AS IS'' AND ANY EXPRESS
28129198Scognet * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
29129198Scognet * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
30129198Scognet * DISCLAIMED. IN NO EVENT SHALL CAUSALITY LIMITED BE LIABLE FOR ANY DIRECT,
31129198Scognet * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
32129198Scognet * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
33129198Scognet * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
34129198Scognet * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
35129198Scognet * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
36129198Scognet * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
37129198Scognet * SUCH DAMAGE.
38129198Scognet *
39129198Scognet * RiscBSD kernel project
40129198Scognet *
41129198Scognet * cpufuncs.c
42129198Scognet *
43129198Scognet * C functions for supporting CPU / MMU / TLB specific operations.
44129198Scognet *
45129198Scognet * Created      : 30/01/97
46129198Scognet */
47129198Scognet#include <sys/cdefs.h>
48129198Scognet__FBSDID("$FreeBSD: head/sys/arm/arm/cpufunc.c 259640 2013-12-20 00:56:23Z ganbold $");
49129198Scognet
50129198Scognet#include <sys/param.h>
51129198Scognet#include <sys/systm.h>
52129198Scognet#include <sys/lock.h>
53129198Scognet#include <sys/mutex.h>
54132472Scognet#include <sys/bus.h>
55132472Scognet#include <machine/bus.h>
56129198Scognet#include <machine/cpu.h>
57129198Scognet#include <machine/disassem.h>
58129198Scognet
59129198Scognet#include <vm/vm.h>
60129198Scognet#include <vm/pmap.h>
61166655Scognet#include <vm/uma.h>
62129198Scognet
63129198Scognet#include <machine/cpuconf.h>
64129198Scognet#include <machine/cpufunc.h>
65129198Scognet#include <machine/bootconfig.h>
66129198Scognet
67129198Scognet#ifdef CPU_XSCALE_80200
68135646Scognet#include <arm/xscale/i80200/i80200reg.h>
69135646Scognet#include <arm/xscale/i80200/i80200var.h>
70129198Scognet#endif
71129198Scognet
72161592Scognet#if defined(CPU_XSCALE_80321) || defined(CPU_XSCALE_80219)
73135646Scognet#include <arm/xscale/i80321/i80321reg.h>
74135646Scognet#include <arm/xscale/i80321/i80321var.h>
75129198Scognet#endif
76129198Scognet
77243579Smarcel/*
78243579Smarcel * Some definitions in i81342reg.h clash with i80321reg.h.
79243579Smarcel * This only happens for the LINT kernel. As it happens,
80243579Smarcel * we don't need anything from i81342reg.h that we already
81243579Smarcel * got from somewhere else during a LINT compile.
82243579Smarcel */
83243579Smarcel#if defined(CPU_XSCALE_81342) && !defined(COMPILING_LINT)
84164080Scognet#include <arm/xscale/i8134x/i81342reg.h>
85164080Scognet#endif
86164080Scognet
87129198Scognet#ifdef CPU_XSCALE_IXP425
88135646Scognet#include <arm/xscale/ixp425/ixp425reg.h>
89135646Scognet#include <arm/xscale/ixp425/ixp425var.h>
90129198Scognet#endif
91129198Scognet
92129198Scognet/* PRIMARY CACHE VARIABLES */
93129198Scognetint	arm_picache_size;
94129198Scognetint	arm_picache_line_size;
95129198Scognetint	arm_picache_ways;
96129198Scognet
97129198Scognetint	arm_pdcache_size;	/* and unified */
98129198Scognetint	arm_pdcache_line_size;
99129198Scognetint	arm_pdcache_ways;
100129198Scognet
101129198Scognetint	arm_pcache_type;
102129198Scognetint	arm_pcache_unified;
103129198Scognet
104129198Scognetint	arm_dcache_align;
105129198Scognetint	arm_dcache_align_mask;
106129198Scognet
107239268Sgonzou_int	arm_cache_level;
108239268Sgonzou_int	arm_cache_type[14];
109239268Sgonzou_int	arm_cache_loc;
110239268Sgonzo
111129198Scognet/* 1 == use cpu_sleep(), 0 == don't */
112129198Scognetint cpu_do_powersave;
113129198Scognetint ctrl;
114129198Scognet
115129198Scognet#ifdef CPU_ARM7TDMI
116129198Scognetstruct cpu_functions arm7tdmi_cpufuncs = {
117129198Scognet	/* CPU functions */
118129198Scognet
119129198Scognet	cpufunc_id,			/* id			*/
120129198Scognet	cpufunc_nullop,			/* cpwait		*/
121129198Scognet
122129198Scognet	/* MMU functions */
123129198Scognet
124129198Scognet	cpufunc_control,		/* control		*/
125129198Scognet	cpufunc_domains,		/* domain		*/
126129198Scognet	arm7tdmi_setttb,		/* setttb		*/
127129198Scognet	cpufunc_faultstatus,		/* faultstatus		*/
128129198Scognet	cpufunc_faultaddress,		/* faultaddress		*/
129129198Scognet
130129198Scognet	/* TLB functions */
131129198Scognet
132129198Scognet	arm7tdmi_tlb_flushID,		/* tlb_flushID		*/
133129198Scognet	arm7tdmi_tlb_flushID_SE,	/* tlb_flushID_SE	*/
134129198Scognet	arm7tdmi_tlb_flushID,		/* tlb_flushI		*/
135129198Scognet	arm7tdmi_tlb_flushID_SE,	/* tlb_flushI_SE	*/
136129198Scognet	arm7tdmi_tlb_flushID,		/* tlb_flushD		*/
137129198Scognet	arm7tdmi_tlb_flushID_SE,	/* tlb_flushD_SE	*/
138129198Scognet
139129198Scognet	/* Cache operations */
140129198Scognet
141129198Scognet	cpufunc_nullop,			/* icache_sync_all	*/
142129198Scognet	(void *)cpufunc_nullop,		/* icache_sync_range	*/
143129198Scognet
144129198Scognet	arm7tdmi_cache_flushID,		/* dcache_wbinv_all	*/
145129198Scognet	(void *)arm7tdmi_cache_flushID,	/* dcache_wbinv_range	*/
146129198Scognet	(void *)arm7tdmi_cache_flushID,	/* dcache_inv_range	*/
147129198Scognet	(void *)cpufunc_nullop,		/* dcache_wb_range	*/
148129198Scognet
149129198Scognet	arm7tdmi_cache_flushID,		/* idcache_wbinv_all	*/
150129198Scognet	(void *)arm7tdmi_cache_flushID,	/* idcache_wbinv_range	*/
151171618Scognet	cpufunc_nullop,			/* l2cache_wbinv_all	*/
152171781Scognet	(void *)cpufunc_nullop,		/* l2cache_wbinv_range	*/
153171781Scognet	(void *)cpufunc_nullop,		/* l2cache_inv_range	*/
154171781Scognet	(void *)cpufunc_nullop,		/* l2cache_wb_range	*/
155129198Scognet
156129198Scognet	/* Other functions */
157129198Scognet
158129198Scognet	cpufunc_nullop,			/* flush_prefetchbuf	*/
159129198Scognet	cpufunc_nullop,			/* drain_writebuf	*/
160129198Scognet	cpufunc_nullop,			/* flush_brnchtgt_C	*/
161129198Scognet	(void *)cpufunc_nullop,		/* flush_brnchtgt_E	*/
162129198Scognet
163129198Scognet	(void *)cpufunc_nullop,		/* sleep		*/
164129198Scognet
165129198Scognet	/* Soft functions */
166129198Scognet
167129198Scognet	late_abort_fixup,		/* dataabt_fixup	*/
168129198Scognet	cpufunc_null_fixup,		/* prefetchabt_fixup	*/
169129198Scognet
170129198Scognet	arm7tdmi_context_switch,	/* context_switch	*/
171129198Scognet
172129198Scognet	arm7tdmi_setup			/* cpu setup		*/
173129198Scognet
174129198Scognet};
175129198Scognet#endif	/* CPU_ARM7TDMI */
176129198Scognet
177129198Scognet#ifdef CPU_ARM8
178129198Scognetstruct cpu_functions arm8_cpufuncs = {
179129198Scognet	/* CPU functions */
180129198Scognet
181129198Scognet	cpufunc_id,			/* id			*/
182129198Scognet	cpufunc_nullop,			/* cpwait		*/
183129198Scognet
184129198Scognet	/* MMU functions */
185129198Scognet
186129198Scognet	cpufunc_control,		/* control		*/
187129198Scognet	cpufunc_domains,		/* domain		*/
188129198Scognet	arm8_setttb,			/* setttb		*/
189129198Scognet	cpufunc_faultstatus,		/* faultstatus		*/
190129198Scognet	cpufunc_faultaddress,		/* faultaddress		*/
191129198Scognet
192129198Scognet	/* TLB functions */
193129198Scognet
194129198Scognet	arm8_tlb_flushID,		/* tlb_flushID		*/
195129198Scognet	arm8_tlb_flushID_SE,		/* tlb_flushID_SE	*/
196129198Scognet	arm8_tlb_flushID,		/* tlb_flushI		*/
197129198Scognet	arm8_tlb_flushID_SE,		/* tlb_flushI_SE	*/
198129198Scognet	arm8_tlb_flushID,		/* tlb_flushD		*/
199129198Scognet	arm8_tlb_flushID_SE,		/* tlb_flushD_SE	*/
200129198Scognet
201129198Scognet	/* Cache operations */
202129198Scognet
203129198Scognet	cpufunc_nullop,			/* icache_sync_all	*/
204129198Scognet	(void *)cpufunc_nullop,		/* icache_sync_range	*/
205129198Scognet
206129198Scognet	arm8_cache_purgeID,		/* dcache_wbinv_all	*/
207129198Scognet	(void *)arm8_cache_purgeID,	/* dcache_wbinv_range	*/
208129198Scognet/*XXX*/	(void *)arm8_cache_purgeID,	/* dcache_inv_range	*/
209129198Scognet	(void *)arm8_cache_cleanID,	/* dcache_wb_range	*/
210129198Scognet
211129198Scognet	arm8_cache_purgeID,		/* idcache_wbinv_all	*/
212129198Scognet	(void *)arm8_cache_purgeID,	/* idcache_wbinv_range	*/
213171618Scognet	cpufunc_nullop,			/* l2cache_wbinv_all	*/
214171781Scognet	(void *)cpufunc_nullop,		/* l2cache_wbinv_range	*/
215171781Scognet	(void *)cpufunc_nullop,		/* l2cache_inv_range	*/
216171781Scognet	(void *)cpufunc_nullop,		/* l2cache_wb_range	*/
217129198Scognet
218129198Scognet	/* Other functions */
219129198Scognet
220129198Scognet	cpufunc_nullop,			/* flush_prefetchbuf	*/
221129198Scognet	cpufunc_nullop,			/* drain_writebuf	*/
222129198Scognet	cpufunc_nullop,			/* flush_brnchtgt_C	*/
223129198Scognet	(void *)cpufunc_nullop,		/* flush_brnchtgt_E	*/
224129198Scognet
225129198Scognet	(void *)cpufunc_nullop,		/* sleep		*/
226129198Scognet
227129198Scognet	/* Soft functions */
228129198Scognet
229129198Scognet	cpufunc_null_fixup,		/* dataabt_fixup	*/
230129198Scognet	cpufunc_null_fixup,		/* prefetchabt_fixup	*/
231129198Scognet
232129198Scognet	arm8_context_switch,		/* context_switch	*/
233129198Scognet
234129198Scognet	arm8_setup			/* cpu setup		*/
235236991Simp};
236129198Scognet#endif	/* CPU_ARM8 */
237129198Scognet
238129198Scognet#ifdef CPU_ARM9
239129198Scognetstruct cpu_functions arm9_cpufuncs = {
240129198Scognet	/* CPU functions */
241129198Scognet
242129198Scognet	cpufunc_id,			/* id			*/
243129198Scognet	cpufunc_nullop,			/* cpwait		*/
244129198Scognet
245129198Scognet	/* MMU functions */
246129198Scognet
247129198Scognet	cpufunc_control,		/* control		*/
248129198Scognet	cpufunc_domains,		/* Domain		*/
249129198Scognet	arm9_setttb,			/* Setttb		*/
250129198Scognet	cpufunc_faultstatus,		/* Faultstatus		*/
251129198Scognet	cpufunc_faultaddress,		/* Faultaddress		*/
252129198Scognet
253129198Scognet	/* TLB functions */
254129198Scognet
255129198Scognet	armv4_tlb_flushID,		/* tlb_flushID		*/
256129198Scognet	arm9_tlb_flushID_SE,		/* tlb_flushID_SE	*/
257129198Scognet	armv4_tlb_flushI,		/* tlb_flushI		*/
258129198Scognet	(void *)armv4_tlb_flushI,	/* tlb_flushI_SE	*/
259129198Scognet	armv4_tlb_flushD,		/* tlb_flushD		*/
260129198Scognet	armv4_tlb_flushD_SE,		/* tlb_flushD_SE	*/
261129198Scognet
262129198Scognet	/* Cache operations */
263129198Scognet
264146605Scognet	arm9_icache_sync_all,		/* icache_sync_all	*/
265146605Scognet	arm9_icache_sync_range,		/* icache_sync_range	*/
266129198Scognet
267146605Scognet	arm9_dcache_wbinv_all,		/* dcache_wbinv_all	*/
268146605Scognet	arm9_dcache_wbinv_range,	/* dcache_wbinv_range	*/
269195798Sraj	arm9_dcache_inv_range,		/* dcache_inv_range	*/
270146605Scognet	arm9_dcache_wb_range,		/* dcache_wb_range	*/
271129198Scognet
272146605Scognet	arm9_idcache_wbinv_all,		/* idcache_wbinv_all	*/
273146605Scognet	arm9_idcache_wbinv_range,	/* idcache_wbinv_range	*/
274171618Scognet	cpufunc_nullop,			/* l2cache_wbinv_all	*/
275171781Scognet	(void *)cpufunc_nullop,		/* l2cache_wbinv_range	*/
276171781Scognet	(void *)cpufunc_nullop,		/* l2cache_inv_range	*/
277171781Scognet	(void *)cpufunc_nullop,		/* l2cache_wb_range	*/
278129198Scognet
279129198Scognet	/* Other functions */
280129198Scognet
281129198Scognet	cpufunc_nullop,			/* flush_prefetchbuf	*/
282129198Scognet	armv4_drain_writebuf,		/* drain_writebuf	*/
283129198Scognet	cpufunc_nullop,			/* flush_brnchtgt_C	*/
284129198Scognet	(void *)cpufunc_nullop,		/* flush_brnchtgt_E	*/
285129198Scognet
286129198Scognet	(void *)cpufunc_nullop,		/* sleep		*/
287129198Scognet
288129198Scognet	/* Soft functions */
289129198Scognet
290129198Scognet	cpufunc_null_fixup,		/* dataabt_fixup	*/
291129198Scognet	cpufunc_null_fixup,		/* prefetchabt_fixup	*/
292129198Scognet
293129198Scognet	arm9_context_switch,		/* context_switch	*/
294129198Scognet
295129198Scognet	arm9_setup			/* cpu setup		*/
296129198Scognet
297129198Scognet};
298129198Scognet#endif /* CPU_ARM9 */
299129198Scognet
300172738Simp#if defined(CPU_ARM9E) || defined(CPU_ARM10)
301172738Simpstruct cpu_functions armv5_ec_cpufuncs = {
302172738Simp	/* CPU functions */
303172738Simp
304172738Simp	cpufunc_id,			/* id			*/
305172738Simp	cpufunc_nullop,			/* cpwait		*/
306172738Simp
307172738Simp	/* MMU functions */
308172738Simp
309172738Simp	cpufunc_control,		/* control		*/
310172738Simp	cpufunc_domains,		/* Domain		*/
311172738Simp	armv5_ec_setttb,		/* Setttb		*/
312172738Simp	cpufunc_faultstatus,		/* Faultstatus		*/
313172738Simp	cpufunc_faultaddress,		/* Faultaddress		*/
314172738Simp
315172738Simp	/* TLB functions */
316172738Simp
317172738Simp	armv4_tlb_flushID,		/* tlb_flushID		*/
318172738Simp	arm10_tlb_flushID_SE,		/* tlb_flushID_SE	*/
319172738Simp	armv4_tlb_flushI,		/* tlb_flushI		*/
320172738Simp	arm10_tlb_flushI_SE,		/* tlb_flushI_SE	*/
321172738Simp	armv4_tlb_flushD,		/* tlb_flushD		*/
322172738Simp	armv4_tlb_flushD_SE,		/* tlb_flushD_SE	*/
323172738Simp
324172738Simp	/* Cache operations */
325172738Simp
326172738Simp	armv5_ec_icache_sync_all,	/* icache_sync_all	*/
327172738Simp	armv5_ec_icache_sync_range,	/* icache_sync_range	*/
328172738Simp
329172738Simp	armv5_ec_dcache_wbinv_all,	/* dcache_wbinv_all	*/
330172738Simp	armv5_ec_dcache_wbinv_range,	/* dcache_wbinv_range	*/
331195798Sraj	armv5_ec_dcache_inv_range,	/* dcache_inv_range	*/
332172738Simp	armv5_ec_dcache_wb_range,	/* dcache_wb_range	*/
333172738Simp
334172738Simp	armv5_ec_idcache_wbinv_all,	/* idcache_wbinv_all	*/
335172738Simp	armv5_ec_idcache_wbinv_range,	/* idcache_wbinv_range	*/
336172738Simp
337173442Scognet	cpufunc_nullop,                 /* l2cache_wbinv_all    */
338173442Scognet	(void *)cpufunc_nullop,         /* l2cache_wbinv_range  */
339173442Scognet      	(void *)cpufunc_nullop,         /* l2cache_inv_range    */
340173442Scognet	(void *)cpufunc_nullop,         /* l2cache_wb_range     */
341236991Simp
342172738Simp	/* Other functions */
343172738Simp
344172738Simp	cpufunc_nullop,			/* flush_prefetchbuf	*/
345172738Simp	armv4_drain_writebuf,		/* drain_writebuf	*/
346172738Simp	cpufunc_nullop,			/* flush_brnchtgt_C	*/
347172738Simp	(void *)cpufunc_nullop,		/* flush_brnchtgt_E	*/
348172738Simp
349172738Simp	(void *)cpufunc_nullop,		/* sleep		*/
350172738Simp
351172738Simp	/* Soft functions */
352172738Simp
353172738Simp	cpufunc_null_fixup,		/* dataabt_fixup	*/
354172738Simp	cpufunc_null_fixup,		/* prefetchabt_fixup	*/
355172738Simp
356172738Simp	arm10_context_switch,		/* context_switch	*/
357172738Simp
358172738Simp	arm10_setup			/* cpu setup		*/
359172738Simp
360172738Simp};
361183835Sraj
362186933Srajstruct cpu_functions sheeva_cpufuncs = {
363183835Sraj	/* CPU functions */
364183835Sraj
365183835Sraj	cpufunc_id,			/* id			*/
366183835Sraj	cpufunc_nullop,			/* cpwait		*/
367183835Sraj
368183835Sraj	/* MMU functions */
369183835Sraj
370183835Sraj	cpufunc_control,		/* control		*/
371183835Sraj	cpufunc_domains,		/* Domain		*/
372186933Sraj	sheeva_setttb,			/* Setttb		*/
373183835Sraj	cpufunc_faultstatus,		/* Faultstatus		*/
374183835Sraj	cpufunc_faultaddress,		/* Faultaddress		*/
375183835Sraj
376183835Sraj	/* TLB functions */
377183835Sraj
378183835Sraj	armv4_tlb_flushID,		/* tlb_flushID		*/
379183835Sraj	arm10_tlb_flushID_SE,		/* tlb_flushID_SE	*/
380183835Sraj	armv4_tlb_flushI,		/* tlb_flushI		*/
381183835Sraj	arm10_tlb_flushI_SE,		/* tlb_flushI_SE	*/
382183835Sraj	armv4_tlb_flushD,		/* tlb_flushD		*/
383183835Sraj	armv4_tlb_flushD_SE,		/* tlb_flushD_SE	*/
384183835Sraj
385183835Sraj	/* Cache operations */
386183835Sraj
387183835Sraj	armv5_ec_icache_sync_all,	/* icache_sync_all	*/
388183835Sraj	armv5_ec_icache_sync_range,	/* icache_sync_range	*/
389183835Sraj
390183835Sraj	armv5_ec_dcache_wbinv_all,	/* dcache_wbinv_all	*/
391186933Sraj	sheeva_dcache_wbinv_range,	/* dcache_wbinv_range	*/
392186933Sraj	sheeva_dcache_inv_range,	/* dcache_inv_range	*/
393186933Sraj	sheeva_dcache_wb_range,		/* dcache_wb_range	*/
394183835Sraj
395183835Sraj	armv5_ec_idcache_wbinv_all,	/* idcache_wbinv_all	*/
396186933Sraj	sheeva_idcache_wbinv_range,	/* idcache_wbinv_all	*/
397183835Sraj
398186933Sraj	sheeva_l2cache_wbinv_all,	/* l2cache_wbinv_all    */
399186933Sraj	sheeva_l2cache_wbinv_range,	/* l2cache_wbinv_range  */
400186933Sraj	sheeva_l2cache_inv_range,	/* l2cache_inv_range    */
401186933Sraj	sheeva_l2cache_wb_range,	/* l2cache_wb_range     */
402183835Sraj
403183835Sraj	/* Other functions */
404183835Sraj
405183835Sraj	cpufunc_nullop,			/* flush_prefetchbuf	*/
406183835Sraj	armv4_drain_writebuf,		/* drain_writebuf	*/
407183835Sraj	cpufunc_nullop,			/* flush_brnchtgt_C	*/
408183835Sraj	(void *)cpufunc_nullop,		/* flush_brnchtgt_E	*/
409183835Sraj
410212825Smav	sheeva_cpu_sleep,		/* sleep		*/
411183835Sraj
412183835Sraj	/* Soft functions */
413183835Sraj
414183835Sraj	cpufunc_null_fixup,		/* dataabt_fixup	*/
415183835Sraj	cpufunc_null_fixup,		/* prefetchabt_fixup	*/
416183835Sraj
417183835Sraj	arm10_context_switch,		/* context_switch	*/
418183835Sraj
419183835Sraj	arm10_setup			/* cpu setup		*/
420183835Sraj};
421172738Simp#endif /* CPU_ARM9E || CPU_ARM10 */
422172738Simp
423129198Scognet#ifdef CPU_ARM10
424129198Scognetstruct cpu_functions arm10_cpufuncs = {
425129198Scognet	/* CPU functions */
426129198Scognet
427129198Scognet	cpufunc_id,			/* id			*/
428129198Scognet	cpufunc_nullop,			/* cpwait		*/
429129198Scognet
430129198Scognet	/* MMU functions */
431129198Scognet
432129198Scognet	cpufunc_control,		/* control		*/
433129198Scognet	cpufunc_domains,		/* Domain		*/
434129198Scognet	arm10_setttb,			/* Setttb		*/
435129198Scognet	cpufunc_faultstatus,		/* Faultstatus		*/
436129198Scognet	cpufunc_faultaddress,		/* Faultaddress		*/
437129198Scognet
438129198Scognet	/* TLB functions */
439129198Scognet
440129198Scognet	armv4_tlb_flushID,		/* tlb_flushID		*/
441129198Scognet	arm10_tlb_flushID_SE,		/* tlb_flushID_SE	*/
442129198Scognet	armv4_tlb_flushI,		/* tlb_flushI		*/
443129198Scognet	arm10_tlb_flushI_SE,		/* tlb_flushI_SE	*/
444129198Scognet	armv4_tlb_flushD,		/* tlb_flushD		*/
445129198Scognet	armv4_tlb_flushD_SE,		/* tlb_flushD_SE	*/
446129198Scognet
447129198Scognet	/* Cache operations */
448129198Scognet
449129198Scognet	arm10_icache_sync_all,		/* icache_sync_all	*/
450129198Scognet	arm10_icache_sync_range,	/* icache_sync_range	*/
451129198Scognet
452129198Scognet	arm10_dcache_wbinv_all,		/* dcache_wbinv_all	*/
453129198Scognet	arm10_dcache_wbinv_range,	/* dcache_wbinv_range	*/
454129198Scognet	arm10_dcache_inv_range,		/* dcache_inv_range	*/
455129198Scognet	arm10_dcache_wb_range,		/* dcache_wb_range	*/
456129198Scognet
457129198Scognet	arm10_idcache_wbinv_all,	/* idcache_wbinv_all	*/
458129198Scognet	arm10_idcache_wbinv_range,	/* idcache_wbinv_range	*/
459171618Scognet	cpufunc_nullop,			/* l2cache_wbinv_all	*/
460171781Scognet	(void *)cpufunc_nullop,		/* l2cache_wbinv_range	*/
461171781Scognet	(void *)cpufunc_nullop,		/* l2cache_inv_range	*/
462171781Scognet	(void *)cpufunc_nullop,		/* l2cache_wb_range	*/
463129198Scognet
464129198Scognet	/* Other functions */
465129198Scognet
466129198Scognet	cpufunc_nullop,			/* flush_prefetchbuf	*/
467129198Scognet	armv4_drain_writebuf,		/* drain_writebuf	*/
468129198Scognet	cpufunc_nullop,			/* flush_brnchtgt_C	*/
469129198Scognet	(void *)cpufunc_nullop,		/* flush_brnchtgt_E	*/
470129198Scognet
471129198Scognet	(void *)cpufunc_nullop,		/* sleep		*/
472129198Scognet
473129198Scognet	/* Soft functions */
474129198Scognet
475129198Scognet	cpufunc_null_fixup,		/* dataabt_fixup	*/
476129198Scognet	cpufunc_null_fixup,		/* prefetchabt_fixup	*/
477129198Scognet
478129198Scognet	arm10_context_switch,		/* context_switch	*/
479129198Scognet
480129198Scognet	arm10_setup			/* cpu setup		*/
481129198Scognet
482129198Scognet};
483129198Scognet#endif /* CPU_ARM10 */
484129198Scognet
485239268Sgonzo#ifdef CPU_MV_PJ4B
486239268Sgonzostruct cpu_functions pj4bv7_cpufuncs = {
487239268Sgonzo	/* CPU functions */
488239268Sgonzo
489239268Sgonzo	cpufunc_id,			/* id			*/
490239268Sgonzo	arm11_drain_writebuf,		/* cpwait		*/
491239268Sgonzo
492239268Sgonzo	/* MMU functions */
493239268Sgonzo
494239268Sgonzo	cpufunc_control,		/* control		*/
495239268Sgonzo	cpufunc_domains,		/* Domain		*/
496239268Sgonzo	pj4b_setttb,			/* Setttb		*/
497239268Sgonzo	cpufunc_faultstatus,		/* Faultstatus		*/
498239268Sgonzo	cpufunc_faultaddress,		/* Faultaddress		*/
499239268Sgonzo
500239268Sgonzo	/* TLB functions */
501239268Sgonzo
502239268Sgonzo	armv7_tlb_flushID,		/* tlb_flushID		*/
503239268Sgonzo	armv7_tlb_flushID_SE,		/* tlb_flushID_SE	*/
504239268Sgonzo	armv7_tlb_flushID,		/* tlb_flushI		*/
505239268Sgonzo	armv7_tlb_flushID_SE,		/* tlb_flushI_SE	*/
506239268Sgonzo	armv7_tlb_flushID,		/* tlb_flushD		*/
507239268Sgonzo	armv7_tlb_flushID_SE,		/* tlb_flushD_SE	*/
508239268Sgonzo
509239268Sgonzo	/* Cache operations */
510239268Sgonzo	armv7_idcache_wbinv_all,	/* icache_sync_all	*/
511239268Sgonzo	armv7_icache_sync_range,	/* icache_sync_range	*/
512239268Sgonzo
513239268Sgonzo	armv7_dcache_wbinv_all,		/* dcache_wbinv_all	*/
514239268Sgonzo	armv7_dcache_wbinv_range,	/* dcache_wbinv_range	*/
515239268Sgonzo	armv7_dcache_inv_range,		/* dcache_inv_range	*/
516239268Sgonzo	armv7_dcache_wb_range,		/* dcache_wb_range	*/
517239268Sgonzo
518239268Sgonzo	armv7_idcache_wbinv_all,	/* idcache_wbinv_all	*/
519239268Sgonzo	armv7_idcache_wbinv_range,	/* idcache_wbinv_all	*/
520239268Sgonzo
521239268Sgonzo	(void *)cpufunc_nullop,		/* l2cache_wbinv_all	*/
522239268Sgonzo	(void *)cpufunc_nullop,		/* l2cache_wbinv_range	*/
523239268Sgonzo	(void *)cpufunc_nullop,		/* l2cache_inv_range	*/
524239268Sgonzo	(void *)cpufunc_nullop,		/* l2cache_wb_range	*/
525239268Sgonzo
526239268Sgonzo	/* Other functions */
527239268Sgonzo
528239268Sgonzo	pj4b_drain_readbuf,		/* flush_prefetchbuf	*/
529239268Sgonzo	arm11_drain_writebuf,		/* drain_writebuf	*/
530239268Sgonzo	pj4b_flush_brnchtgt_all,	/* flush_brnchtgt_C	*/
531239268Sgonzo	pj4b_flush_brnchtgt_va,		/* flush_brnchtgt_E	*/
532239268Sgonzo
533239268Sgonzo	(void *)cpufunc_nullop,		/* sleep		*/
534239268Sgonzo
535239268Sgonzo	/* Soft functions */
536239268Sgonzo
537239268Sgonzo	cpufunc_null_fixup,		/* dataabt_fixup	*/
538239268Sgonzo	cpufunc_null_fixup,		/* prefetchabt_fixup	*/
539239268Sgonzo
540239268Sgonzo	arm11_context_switch,		/* context_switch	*/
541239268Sgonzo
542239268Sgonzo	pj4bv7_setup			/* cpu setup		*/
543239268Sgonzo};
544239268Sgonzo#endif /* CPU_MV_PJ4B */
545239268Sgonzo
546129198Scognet#ifdef CPU_SA110
547129198Scognetstruct cpu_functions sa110_cpufuncs = {
548129198Scognet	/* CPU functions */
549129198Scognet
550129198Scognet	cpufunc_id,			/* id			*/
551129198Scognet	cpufunc_nullop,			/* cpwait		*/
552129198Scognet
553129198Scognet	/* MMU functions */
554129198Scognet
555129198Scognet	cpufunc_control,		/* control		*/
556129198Scognet	cpufunc_domains,		/* domain		*/
557129198Scognet	sa1_setttb,			/* setttb		*/
558129198Scognet	cpufunc_faultstatus,		/* faultstatus		*/
559129198Scognet	cpufunc_faultaddress,		/* faultaddress		*/
560129198Scognet
561129198Scognet	/* TLB functions */
562129198Scognet
563129198Scognet	armv4_tlb_flushID,		/* tlb_flushID		*/
564129198Scognet	sa1_tlb_flushID_SE,		/* tlb_flushID_SE	*/
565129198Scognet	armv4_tlb_flushI,		/* tlb_flushI		*/
566129198Scognet	(void *)armv4_tlb_flushI,	/* tlb_flushI_SE	*/
567129198Scognet	armv4_tlb_flushD,		/* tlb_flushD		*/
568129198Scognet	armv4_tlb_flushD_SE,		/* tlb_flushD_SE	*/
569129198Scognet
570129198Scognet	/* Cache operations */
571129198Scognet
572129198Scognet	sa1_cache_syncI,		/* icache_sync_all	*/
573129198Scognet	sa1_cache_syncI_rng,		/* icache_sync_range	*/
574129198Scognet
575129198Scognet	sa1_cache_purgeD,		/* dcache_wbinv_all	*/
576129198Scognet	sa1_cache_purgeD_rng,		/* dcache_wbinv_range	*/
577129198Scognet/*XXX*/	sa1_cache_purgeD_rng,		/* dcache_inv_range	*/
578129198Scognet	sa1_cache_cleanD_rng,		/* dcache_wb_range	*/
579129198Scognet
580129198Scognet	sa1_cache_purgeID,		/* idcache_wbinv_all	*/
581129198Scognet	sa1_cache_purgeID_rng,		/* idcache_wbinv_range	*/
582171618Scognet	cpufunc_nullop,			/* l2cache_wbinv_all	*/
583171781Scognet	(void *)cpufunc_nullop,		/* l2cache_wbinv_range	*/
584171781Scognet	(void *)cpufunc_nullop,		/* l2cache_inv_range	*/
585171781Scognet	(void *)cpufunc_nullop,		/* l2cache_wb_range	*/
586129198Scognet
587129198Scognet	/* Other functions */
588129198Scognet
589129198Scognet	cpufunc_nullop,			/* flush_prefetchbuf	*/
590129198Scognet	armv4_drain_writebuf,		/* drain_writebuf	*/
591129198Scognet	cpufunc_nullop,			/* flush_brnchtgt_C	*/
592129198Scognet	(void *)cpufunc_nullop,		/* flush_brnchtgt_E	*/
593129198Scognet
594129198Scognet	(void *)cpufunc_nullop,		/* sleep		*/
595129198Scognet
596129198Scognet	/* Soft functions */
597129198Scognet
598129198Scognet	cpufunc_null_fixup,		/* dataabt_fixup	*/
599129198Scognet	cpufunc_null_fixup,		/* prefetchabt_fixup	*/
600129198Scognet
601129198Scognet	sa110_context_switch,		/* context_switch	*/
602129198Scognet
603129198Scognet	sa110_setup			/* cpu setup		*/
604236991Simp};
605129198Scognet#endif	/* CPU_SA110 */
606129198Scognet
607129198Scognet#if defined(CPU_SA1100) || defined(CPU_SA1110)
608129198Scognetstruct cpu_functions sa11x0_cpufuncs = {
609129198Scognet	/* CPU functions */
610129198Scognet
611129198Scognet	cpufunc_id,			/* id			*/
612129198Scognet	cpufunc_nullop,			/* cpwait		*/
613129198Scognet
614129198Scognet	/* MMU functions */
615129198Scognet
616129198Scognet	cpufunc_control,		/* control		*/
617129198Scognet	cpufunc_domains,		/* domain		*/
618129198Scognet	sa1_setttb,			/* setttb		*/
619129198Scognet	cpufunc_faultstatus,		/* faultstatus		*/
620129198Scognet	cpufunc_faultaddress,		/* faultaddress		*/
621129198Scognet
622129198Scognet	/* TLB functions */
623129198Scognet
624129198Scognet	armv4_tlb_flushID,		/* tlb_flushID		*/
625129198Scognet	sa1_tlb_flushID_SE,		/* tlb_flushID_SE	*/
626129198Scognet	armv4_tlb_flushI,		/* tlb_flushI		*/
627129198Scognet	(void *)armv4_tlb_flushI,	/* tlb_flushI_SE	*/
628129198Scognet	armv4_tlb_flushD,		/* tlb_flushD		*/
629129198Scognet	armv4_tlb_flushD_SE,		/* tlb_flushD_SE	*/
630129198Scognet
631129198Scognet	/* Cache operations */
632129198Scognet
633129198Scognet	sa1_cache_syncI,		/* icache_sync_all	*/
634129198Scognet	sa1_cache_syncI_rng,		/* icache_sync_range	*/
635129198Scognet
636129198Scognet	sa1_cache_purgeD,		/* dcache_wbinv_all	*/
637129198Scognet	sa1_cache_purgeD_rng,		/* dcache_wbinv_range	*/
638129198Scognet/*XXX*/	sa1_cache_purgeD_rng,		/* dcache_inv_range	*/
639129198Scognet	sa1_cache_cleanD_rng,		/* dcache_wb_range	*/
640129198Scognet
641129198Scognet	sa1_cache_purgeID,		/* idcache_wbinv_all	*/
642129198Scognet	sa1_cache_purgeID_rng,		/* idcache_wbinv_range	*/
643171618Scognet	cpufunc_nullop,			/* l2cache_wbinv_all	*/
644171781Scognet	(void *)cpufunc_nullop,		/* l2cache_wbinv_range	*/
645171781Scognet	(void *)cpufunc_nullop,		/* l2cache_inv_range	*/
646171781Scognet	(void *)cpufunc_nullop,		/* l2cache_wb_range	*/
647129198Scognet
648129198Scognet	/* Other functions */
649129198Scognet
650129198Scognet	sa11x0_drain_readbuf,		/* flush_prefetchbuf	*/
651129198Scognet	armv4_drain_writebuf,		/* drain_writebuf	*/
652129198Scognet	cpufunc_nullop,			/* flush_brnchtgt_C	*/
653129198Scognet	(void *)cpufunc_nullop,		/* flush_brnchtgt_E	*/
654129198Scognet
655129198Scognet	sa11x0_cpu_sleep,		/* sleep		*/
656129198Scognet
657129198Scognet	/* Soft functions */
658129198Scognet
659129198Scognet	cpufunc_null_fixup,		/* dataabt_fixup	*/
660129198Scognet	cpufunc_null_fixup,		/* prefetchabt_fixup	*/
661129198Scognet
662129198Scognet	sa11x0_context_switch,		/* context_switch	*/
663129198Scognet
664129198Scognet	sa11x0_setup			/* cpu setup		*/
665236991Simp};
666129198Scognet#endif	/* CPU_SA1100 || CPU_SA1110 */
667129198Scognet
668129198Scognet#ifdef CPU_IXP12X0
669129198Scognetstruct cpu_functions ixp12x0_cpufuncs = {
670129198Scognet	/* CPU functions */
671129198Scognet
672129198Scognet	cpufunc_id,			/* id			*/
673129198Scognet	cpufunc_nullop,			/* cpwait		*/
674129198Scognet
675129198Scognet	/* MMU functions */
676129198Scognet
677129198Scognet	cpufunc_control,		/* control		*/
678129198Scognet	cpufunc_domains,		/* domain		*/
679129198Scognet	sa1_setttb,			/* setttb		*/
680129198Scognet	cpufunc_faultstatus,		/* faultstatus		*/
681129198Scognet	cpufunc_faultaddress,		/* faultaddress		*/
682129198Scognet
683129198Scognet	/* TLB functions */
684129198Scognet
685129198Scognet	armv4_tlb_flushID,		/* tlb_flushID		*/
686129198Scognet	sa1_tlb_flushID_SE,		/* tlb_flushID_SE	*/
687129198Scognet	armv4_tlb_flushI,		/* tlb_flushI		*/
688129198Scognet	(void *)armv4_tlb_flushI,	/* tlb_flushI_SE	*/
689129198Scognet	armv4_tlb_flushD,		/* tlb_flushD		*/
690129198Scognet	armv4_tlb_flushD_SE,		/* tlb_flushD_SE	*/
691129198Scognet
692129198Scognet	/* Cache operations */
693129198Scognet
694129198Scognet	sa1_cache_syncI,		/* icache_sync_all	*/
695129198Scognet	sa1_cache_syncI_rng,		/* icache_sync_range	*/
696129198Scognet
697129198Scognet	sa1_cache_purgeD,		/* dcache_wbinv_all	*/
698129198Scognet	sa1_cache_purgeD_rng,		/* dcache_wbinv_range	*/
699129198Scognet/*XXX*/	sa1_cache_purgeD_rng,		/* dcache_inv_range	*/
700129198Scognet	sa1_cache_cleanD_rng,		/* dcache_wb_range	*/
701129198Scognet
702129198Scognet	sa1_cache_purgeID,		/* idcache_wbinv_all	*/
703129198Scognet	sa1_cache_purgeID_rng,		/* idcache_wbinv_range	*/
704171618Scognet	cpufunc_nullop,			/* l2cache_wbinv_all	*/
705171781Scognet	(void *)cpufunc_nullop,		/* l2cache_wbinv_range	*/
706171781Scognet	(void *)cpufunc_nullop,		/* l2cache_inv_range	*/
707171781Scognet	(void *)cpufunc_nullop,		/* l2cache_wb_range	*/
708129198Scognet
709129198Scognet	/* Other functions */
710129198Scognet
711129198Scognet	ixp12x0_drain_readbuf,			/* flush_prefetchbuf	*/
712129198Scognet	armv4_drain_writebuf,		/* drain_writebuf	*/
713129198Scognet	cpufunc_nullop,			/* flush_brnchtgt_C	*/
714129198Scognet	(void *)cpufunc_nullop,		/* flush_brnchtgt_E	*/
715129198Scognet
716129198Scognet	(void *)cpufunc_nullop,		/* sleep		*/
717129198Scognet
718129198Scognet	/* Soft functions */
719129198Scognet
720129198Scognet	cpufunc_null_fixup,		/* dataabt_fixup	*/
721129198Scognet	cpufunc_null_fixup,		/* prefetchabt_fixup	*/
722129198Scognet
723129198Scognet	ixp12x0_context_switch,		/* context_switch	*/
724129198Scognet
725129198Scognet	ixp12x0_setup			/* cpu setup		*/
726236991Simp};
727129198Scognet#endif	/* CPU_IXP12X0 */
728129198Scognet
729129198Scognet#if defined(CPU_XSCALE_80200) || defined(CPU_XSCALE_80321) || \
730161592Scognet  defined(CPU_XSCALE_PXA2X0) || defined(CPU_XSCALE_IXP425) || \
731161592Scognet  defined(CPU_XSCALE_80219)
732161592Scognet
733129198Scognetstruct cpu_functions xscale_cpufuncs = {
734129198Scognet	/* CPU functions */
735129198Scognet
736129198Scognet	cpufunc_id,			/* id			*/
737129198Scognet	xscale_cpwait,			/* cpwait		*/
738129198Scognet
739129198Scognet	/* MMU functions */
740129198Scognet
741129198Scognet	xscale_control,			/* control		*/
742129198Scognet	cpufunc_domains,		/* domain		*/
743129198Scognet	xscale_setttb,			/* setttb		*/
744129198Scognet	cpufunc_faultstatus,		/* faultstatus		*/
745129198Scognet	cpufunc_faultaddress,		/* faultaddress		*/
746129198Scognet
747129198Scognet	/* TLB functions */
748129198Scognet
749129198Scognet	armv4_tlb_flushID,		/* tlb_flushID		*/
750129198Scognet	xscale_tlb_flushID_SE,		/* tlb_flushID_SE	*/
751129198Scognet	armv4_tlb_flushI,		/* tlb_flushI		*/
752129198Scognet	(void *)armv4_tlb_flushI,	/* tlb_flushI_SE	*/
753129198Scognet	armv4_tlb_flushD,		/* tlb_flushD		*/
754129198Scognet	armv4_tlb_flushD_SE,		/* tlb_flushD_SE	*/
755129198Scognet
756129198Scognet	/* Cache operations */
757129198Scognet
758129198Scognet	xscale_cache_syncI,		/* icache_sync_all	*/
759129198Scognet	xscale_cache_syncI_rng,		/* icache_sync_range	*/
760129198Scognet
761129198Scognet	xscale_cache_purgeD,		/* dcache_wbinv_all	*/
762129198Scognet	xscale_cache_purgeD_rng,	/* dcache_wbinv_range	*/
763129198Scognet	xscale_cache_flushD_rng,	/* dcache_inv_range	*/
764129198Scognet	xscale_cache_cleanD_rng,	/* dcache_wb_range	*/
765129198Scognet
766129198Scognet	xscale_cache_purgeID,		/* idcache_wbinv_all	*/
767129198Scognet	xscale_cache_purgeID_rng,	/* idcache_wbinv_range	*/
768171618Scognet	cpufunc_nullop,			/* l2cache_wbinv_all 	*/
769171781Scognet	(void *)cpufunc_nullop,		/* l2cache_wbinv_range	*/
770171781Scognet	(void *)cpufunc_nullop,		/* l2cache_inv_range	*/
771171781Scognet	(void *)cpufunc_nullop,		/* l2cache_wb_range	*/
772129198Scognet
773129198Scognet	/* Other functions */
774129198Scognet
775129198Scognet	cpufunc_nullop,			/* flush_prefetchbuf	*/
776129198Scognet	armv4_drain_writebuf,		/* drain_writebuf	*/
777129198Scognet	cpufunc_nullop,			/* flush_brnchtgt_C	*/
778129198Scognet	(void *)cpufunc_nullop,		/* flush_brnchtgt_E	*/
779129198Scognet
780129198Scognet	xscale_cpu_sleep,		/* sleep		*/
781129198Scognet
782129198Scognet	/* Soft functions */
783129198Scognet
784129198Scognet	cpufunc_null_fixup,		/* dataabt_fixup	*/
785129198Scognet	cpufunc_null_fixup,		/* prefetchabt_fixup	*/
786129198Scognet
787129198Scognet	xscale_context_switch,		/* context_switch	*/
788129198Scognet
789129198Scognet	xscale_setup			/* cpu setup		*/
790129198Scognet};
791129198Scognet#endif
792161592Scognet/* CPU_XSCALE_80200 || CPU_XSCALE_80321 || CPU_XSCALE_PXA2X0 || CPU_XSCALE_IXP425
793161592Scognet   CPU_XSCALE_80219 */
794129198Scognet
795164080Scognet#ifdef CPU_XSCALE_81342
796164080Scognetstruct cpu_functions xscalec3_cpufuncs = {
797164080Scognet	/* CPU functions */
798164080Scognet
799164080Scognet	cpufunc_id,			/* id			*/
800164080Scognet	xscale_cpwait,			/* cpwait		*/
801164080Scognet
802164080Scognet	/* MMU functions */
803164080Scognet
804164080Scognet	xscale_control,			/* control		*/
805164080Scognet	cpufunc_domains,		/* domain		*/
806164080Scognet	xscalec3_setttb,		/* setttb		*/
807164080Scognet	cpufunc_faultstatus,		/* faultstatus		*/
808164080Scognet	cpufunc_faultaddress,		/* faultaddress		*/
809164080Scognet
810164080Scognet	/* TLB functions */
811164080Scognet
812164080Scognet	armv4_tlb_flushID,		/* tlb_flushID		*/
813164080Scognet	xscale_tlb_flushID_SE,		/* tlb_flushID_SE	*/
814164080Scognet	armv4_tlb_flushI,		/* tlb_flushI		*/
815164080Scognet	(void *)armv4_tlb_flushI,	/* tlb_flushI_SE	*/
816164080Scognet	armv4_tlb_flushD,		/* tlb_flushD		*/
817164080Scognet	armv4_tlb_flushD_SE,		/* tlb_flushD_SE	*/
818164080Scognet
819164080Scognet	/* Cache operations */
820164080Scognet
821164080Scognet	xscalec3_cache_syncI,		/* icache_sync_all	*/
822171618Scognet	xscalec3_cache_syncI_rng,	/* icache_sync_range	*/
823164080Scognet
824164080Scognet	xscalec3_cache_purgeD,		/* dcache_wbinv_all	*/
825164080Scognet	xscalec3_cache_purgeD_rng,	/* dcache_wbinv_range	*/
826164080Scognet	xscale_cache_flushD_rng,	/* dcache_inv_range	*/
827164080Scognet	xscalec3_cache_cleanD_rng,	/* dcache_wb_range	*/
828164080Scognet
829171618Scognet	xscalec3_cache_purgeID,		/* idcache_wbinv_all	*/
830164080Scognet	xscalec3_cache_purgeID_rng,	/* idcache_wbinv_range	*/
831171618Scognet	xscalec3_l2cache_purge,		/* l2cache_wbinv_all	*/
832171618Scognet	xscalec3_l2cache_purge_rng,	/* l2cache_wbinv_range	*/
833171618Scognet	xscalec3_l2cache_flush_rng,	/* l2cache_inv_range	*/
834171618Scognet	xscalec3_l2cache_clean_rng,	/* l2cache_wb_range	*/
835164080Scognet
836164080Scognet	/* Other functions */
837164080Scognet
838164080Scognet	cpufunc_nullop,			/* flush_prefetchbuf	*/
839164080Scognet	armv4_drain_writebuf,		/* drain_writebuf	*/
840164080Scognet	cpufunc_nullop,			/* flush_brnchtgt_C	*/
841164080Scognet	(void *)cpufunc_nullop,		/* flush_brnchtgt_E	*/
842164080Scognet
843164080Scognet	xscale_cpu_sleep,		/* sleep		*/
844164080Scognet
845164080Scognet	/* Soft functions */
846164080Scognet
847164080Scognet	cpufunc_null_fixup,		/* dataabt_fixup	*/
848164080Scognet	cpufunc_null_fixup,		/* prefetchabt_fixup	*/
849164080Scognet
850164080Scognet	xscalec3_context_switch,	/* context_switch	*/
851164080Scognet
852164080Scognet	xscale_setup			/* cpu setup		*/
853164080Scognet};
854164080Scognet#endif /* CPU_XSCALE_81342 */
855201468Srpaulo
856201468Srpaulo
857207611Skevlo#if defined(CPU_FA526) || defined(CPU_FA626TE)
858201468Srpaulostruct cpu_functions fa526_cpufuncs = {
859201468Srpaulo	/* CPU functions */
860201468Srpaulo
861207611Skevlo	cpufunc_id,			/* id			*/
862207611Skevlo	cpufunc_nullop,			/* cpwait		*/
863201468Srpaulo
864201468Srpaulo	/* MMU functions */
865201468Srpaulo
866207611Skevlo	cpufunc_control,		/* control		*/
867207611Skevlo	cpufunc_domains,		/* domain		*/
868207611Skevlo	fa526_setttb,			/* setttb		*/
869207611Skevlo	cpufunc_faultstatus,		/* faultstatus		*/
870207611Skevlo	cpufunc_faultaddress,		/* faultaddress		*/
871201468Srpaulo
872201468Srpaulo	/* TLB functions */
873201468Srpaulo
874207611Skevlo	armv4_tlb_flushID,		/* tlb_flushID		*/
875207611Skevlo	fa526_tlb_flushID_SE,		/* tlb_flushID_SE	*/
876207611Skevlo	armv4_tlb_flushI,		/* tlb_flushI		*/
877207611Skevlo	fa526_tlb_flushI_SE,		/* tlb_flushI_SE	*/
878207611Skevlo	armv4_tlb_flushD,		/* tlb_flushD		*/
879207611Skevlo	armv4_tlb_flushD_SE,		/* tlb_flushD_SE	*/
880201468Srpaulo
881201468Srpaulo	/* Cache operations */
882201468Srpaulo
883207611Skevlo	fa526_icache_sync_all,		/* icache_sync_all	*/
884207611Skevlo	fa526_icache_sync_range,	/* icache_sync_range	*/
885201468Srpaulo
886207611Skevlo	fa526_dcache_wbinv_all,		/* dcache_wbinv_all	*/
887207611Skevlo	fa526_dcache_wbinv_range,	/* dcache_wbinv_range	*/
888207611Skevlo	fa526_dcache_inv_range,		/* dcache_inv_range	*/
889207611Skevlo	fa526_dcache_wb_range,		/* dcache_wb_range	*/
890201468Srpaulo
891207611Skevlo	fa526_idcache_wbinv_all,	/* idcache_wbinv_all	*/
892207611Skevlo	fa526_idcache_wbinv_range,	/* idcache_wbinv_range	*/
893207611Skevlo	cpufunc_nullop,			/* l2cache_wbinv_all	*/
894207611Skevlo	(void *)cpufunc_nullop,		/* l2cache_wbinv_range	*/
895207611Skevlo	(void *)cpufunc_nullop,		/* l2cache_inv_range	*/
896207611Skevlo	(void *)cpufunc_nullop,		/* l2cache_wb_range	*/
897201468Srpaulo
898201468Srpaulo	/* Other functions */
899201468Srpaulo
900207611Skevlo	fa526_flush_prefetchbuf,	/* flush_prefetchbuf	*/
901207611Skevlo	armv4_drain_writebuf,		/* drain_writebuf	*/
902207611Skevlo	cpufunc_nullop,			/* flush_brnchtgt_C	*/
903207611Skevlo	fa526_flush_brnchtgt_E,		/* flush_brnchtgt_E	*/
904201468Srpaulo
905207611Skevlo	fa526_cpu_sleep,		/* sleep		*/
906201468Srpaulo
907201468Srpaulo	/* Soft functions */
908201468Srpaulo
909207611Skevlo	cpufunc_null_fixup,		/* dataabt_fixup	*/
910207611Skevlo	cpufunc_null_fixup,		/* prefetchabt_fixup	*/
911201468Srpaulo
912207611Skevlo	fa526_context_switch,		/* context_switch	*/
913201468Srpaulo
914207611Skevlo	fa526_setup			/* cpu setup 		*/
915236991Simp};
916207611Skevlo#endif	/* CPU_FA526 || CPU_FA626TE */
917201468Srpaulo
918244480Sgonzo#if defined(CPU_ARM1136)
919244480Sgonzostruct cpu_functions arm1136_cpufuncs = {
920239701Sgonzo	/* CPU functions */
921239701Sgonzo
922239701Sgonzo	cpufunc_id,                     /* id                   */
923244480Sgonzo	cpufunc_nullop,                 /* cpwait               */
924239701Sgonzo
925239701Sgonzo	/* MMU functions */
926239701Sgonzo
927239701Sgonzo	cpufunc_control,                /* control              */
928239701Sgonzo	cpufunc_domains,                /* Domain               */
929244480Sgonzo	arm11x6_setttb,                 /* Setttb               */
930239701Sgonzo	cpufunc_faultstatus,            /* Faultstatus          */
931239701Sgonzo	cpufunc_faultaddress,           /* Faultaddress         */
932239701Sgonzo
933239701Sgonzo	/* TLB functions */
934239701Sgonzo
935239701Sgonzo	arm11_tlb_flushID,              /* tlb_flushID          */
936239701Sgonzo	arm11_tlb_flushID_SE,           /* tlb_flushID_SE       */
937239701Sgonzo	arm11_tlb_flushI,               /* tlb_flushI           */
938239701Sgonzo	arm11_tlb_flushI_SE,            /* tlb_flushI_SE        */
939239701Sgonzo	arm11_tlb_flushD,               /* tlb_flushD           */
940239701Sgonzo	arm11_tlb_flushD_SE,            /* tlb_flushD_SE        */
941239701Sgonzo
942239701Sgonzo	/* Cache operations */
943239701Sgonzo
944244480Sgonzo	arm11x6_icache_sync_all,        /* icache_sync_all      */
945244480Sgonzo	arm11x6_icache_sync_range,      /* icache_sync_range    */
946239701Sgonzo
947244480Sgonzo	arm11x6_dcache_wbinv_all,       /* dcache_wbinv_all     */
948239701Sgonzo	armv6_dcache_wbinv_range,       /* dcache_wbinv_range   */
949239701Sgonzo	armv6_dcache_inv_range,         /* dcache_inv_range     */
950239701Sgonzo	armv6_dcache_wb_range,          /* dcache_wb_range      */
951239701Sgonzo
952244480Sgonzo	arm11x6_idcache_wbinv_all,      /* idcache_wbinv_all    */
953244480Sgonzo	arm11x6_idcache_wbinv_range,    /* idcache_wbinv_range  */
954239701Sgonzo
955244480Sgonzo	(void *)cpufunc_nullop,         /* l2cache_wbinv_all    */
956239701Sgonzo	(void *)cpufunc_nullop,         /* l2cache_wbinv_range  */
957239701Sgonzo	(void *)cpufunc_nullop,         /* l2cache_inv_range    */
958239701Sgonzo	(void *)cpufunc_nullop,         /* l2cache_wb_range     */
959239701Sgonzo
960239701Sgonzo	/* Other functions */
961239701Sgonzo
962244480Sgonzo	arm11x6_flush_prefetchbuf,      /* flush_prefetchbuf    */
963239701Sgonzo	arm11_drain_writebuf,           /* drain_writebuf       */
964239701Sgonzo	cpufunc_nullop,                 /* flush_brnchtgt_C     */
965239701Sgonzo	(void *)cpufunc_nullop,         /* flush_brnchtgt_E     */
966239701Sgonzo
967244480Sgonzo	arm11_sleep,                  	/* sleep                */
968239701Sgonzo
969239701Sgonzo	/* Soft functions */
970239701Sgonzo
971239701Sgonzo	cpufunc_null_fixup,             /* dataabt_fixup        */
972239701Sgonzo	cpufunc_null_fixup,             /* prefetchabt_fixup    */
973239701Sgonzo
974239701Sgonzo	arm11_context_switch,           /* context_switch       */
975239701Sgonzo
976244480Sgonzo	arm11x6_setup                   /* cpu setup            */
977239701Sgonzo};
978244480Sgonzo#endif /* CPU_ARM1136 */
979244480Sgonzo#if defined(CPU_ARM1176)
980244480Sgonzostruct cpu_functions arm1176_cpufuncs = {
981244480Sgonzo	/* CPU functions */
982244480Sgonzo
983244480Sgonzo	cpufunc_id,                     /* id                   */
984244480Sgonzo	cpufunc_nullop,                 /* cpwait               */
985244480Sgonzo
986244480Sgonzo	/* MMU functions */
987244480Sgonzo
988244480Sgonzo	cpufunc_control,                /* control              */
989244480Sgonzo	cpufunc_domains,                /* Domain               */
990244480Sgonzo	arm11x6_setttb,                 /* Setttb               */
991244480Sgonzo	cpufunc_faultstatus,            /* Faultstatus          */
992244480Sgonzo	cpufunc_faultaddress,           /* Faultaddress         */
993244480Sgonzo
994244480Sgonzo	/* TLB functions */
995244480Sgonzo
996244480Sgonzo	arm11_tlb_flushID,              /* tlb_flushID          */
997244480Sgonzo	arm11_tlb_flushID_SE,           /* tlb_flushID_SE       */
998244480Sgonzo	arm11_tlb_flushI,               /* tlb_flushI           */
999244480Sgonzo	arm11_tlb_flushI_SE,            /* tlb_flushI_SE        */
1000244480Sgonzo	arm11_tlb_flushD,               /* tlb_flushD           */
1001244480Sgonzo	arm11_tlb_flushD_SE,            /* tlb_flushD_SE        */
1002244480Sgonzo
1003244480Sgonzo	/* Cache operations */
1004244480Sgonzo
1005244480Sgonzo	arm11x6_icache_sync_all,        /* icache_sync_all      */
1006244480Sgonzo	arm11x6_icache_sync_range,      /* icache_sync_range    */
1007244480Sgonzo
1008244480Sgonzo	arm11x6_dcache_wbinv_all,       /* dcache_wbinv_all     */
1009244480Sgonzo	armv6_dcache_wbinv_range,       /* dcache_wbinv_range   */
1010244480Sgonzo	armv6_dcache_inv_range,         /* dcache_inv_range     */
1011244480Sgonzo	armv6_dcache_wb_range,          /* dcache_wb_range      */
1012244480Sgonzo
1013244480Sgonzo	arm11x6_idcache_wbinv_all,      /* idcache_wbinv_all    */
1014244480Sgonzo	arm11x6_idcache_wbinv_range,    /* idcache_wbinv_range  */
1015244480Sgonzo
1016244480Sgonzo	(void *)cpufunc_nullop,         /* l2cache_wbinv_all    */
1017244480Sgonzo	(void *)cpufunc_nullop,         /* l2cache_wbinv_range  */
1018244480Sgonzo	(void *)cpufunc_nullop,         /* l2cache_inv_range    */
1019244480Sgonzo	(void *)cpufunc_nullop,         /* l2cache_wb_range     */
1020244480Sgonzo
1021244480Sgonzo	/* Other functions */
1022244480Sgonzo
1023244480Sgonzo	arm11x6_flush_prefetchbuf,      /* flush_prefetchbuf    */
1024244480Sgonzo	arm11_drain_writebuf,           /* drain_writebuf       */
1025244480Sgonzo	cpufunc_nullop,                 /* flush_brnchtgt_C     */
1026244480Sgonzo	(void *)cpufunc_nullop,         /* flush_brnchtgt_E     */
1027244480Sgonzo
1028244480Sgonzo	arm11x6_sleep,                  /* sleep                */
1029244480Sgonzo
1030244480Sgonzo	/* Soft functions */
1031244480Sgonzo
1032244480Sgonzo	cpufunc_null_fixup,             /* dataabt_fixup        */
1033244480Sgonzo	cpufunc_null_fixup,             /* prefetchabt_fixup    */
1034244480Sgonzo
1035244480Sgonzo	arm11_context_switch,           /* context_switch       */
1036244480Sgonzo
1037244480Sgonzo	arm11x6_setup                   /* cpu setup            */
1038244480Sgonzo};
1039244480Sgonzo#endif /*CPU_ARM1176 */
1040239701Sgonzo
1041259640Sganbold#if defined(CPU_CORTEXA) || defined(CPU_KRAIT)
1042239268Sgonzostruct cpu_functions cortexa_cpufuncs = {
1043239268Sgonzo	/* CPU functions */
1044239268Sgonzo
1045239268Sgonzo	cpufunc_id,                     /* id                   */
1046239268Sgonzo	cpufunc_nullop,                 /* cpwait               */
1047239268Sgonzo
1048239268Sgonzo	/* MMU functions */
1049239268Sgonzo
1050239268Sgonzo	cpufunc_control,                /* control              */
1051239268Sgonzo	cpufunc_domains,                /* Domain               */
1052239268Sgonzo	armv7_setttb,                   /* Setttb               */
1053239268Sgonzo	cpufunc_faultstatus,            /* Faultstatus          */
1054239268Sgonzo	cpufunc_faultaddress,           /* Faultaddress         */
1055239268Sgonzo
1056239268Sgonzo	/* TLB functions */
1057239268Sgonzo
1058243024Scognet	armv7_tlb_flushID,              /* tlb_flushID          */
1059239268Sgonzo	armv7_tlb_flushID_SE,           /* tlb_flushID_SE       */
1060239268Sgonzo	arm11_tlb_flushI,               /* tlb_flushI           */
1061239268Sgonzo	arm11_tlb_flushI_SE,            /* tlb_flushI_SE        */
1062239268Sgonzo	arm11_tlb_flushD,               /* tlb_flushD           */
1063239268Sgonzo	arm11_tlb_flushD_SE,            /* tlb_flushD_SE        */
1064239268Sgonzo
1065239268Sgonzo	/* Cache operations */
1066239268Sgonzo
1067239268Sgonzo	armv7_idcache_wbinv_all,         /* icache_sync_all      */
1068239268Sgonzo	armv7_icache_sync_range,        /* icache_sync_range    */
1069239268Sgonzo
1070239268Sgonzo	armv7_dcache_wbinv_all,         /* dcache_wbinv_all     */
1071239268Sgonzo	armv7_dcache_wbinv_range,       /* dcache_wbinv_range   */
1072239268Sgonzo	armv7_dcache_inv_range,         /* dcache_inv_range     */
1073239268Sgonzo	armv7_dcache_wb_range,          /* dcache_wb_range      */
1074239268Sgonzo
1075239268Sgonzo	armv7_idcache_wbinv_all,        /* idcache_wbinv_all    */
1076239268Sgonzo	armv7_idcache_wbinv_range,      /* idcache_wbinv_range  */
1077239268Sgonzo
1078243026Scognet	/*
1079243026Scognet	 * Note: For CPUs using the PL310 the L2 ops are filled in when the
1080239268Sgonzo	 * L2 cache controller is actually enabled.
1081239268Sgonzo	 */
1082239268Sgonzo	cpufunc_nullop,                 /* l2cache_wbinv_all    */
1083239268Sgonzo	(void *)cpufunc_nullop,         /* l2cache_wbinv_range  */
1084239268Sgonzo	(void *)cpufunc_nullop,         /* l2cache_inv_range    */
1085239268Sgonzo	(void *)cpufunc_nullop,         /* l2cache_wb_range     */
1086239268Sgonzo
1087239268Sgonzo	/* Other functions */
1088239268Sgonzo
1089239268Sgonzo	cpufunc_nullop,                 /* flush_prefetchbuf    */
1090245478Scognet	armv7_drain_writebuf,           /* drain_writebuf       */
1091239268Sgonzo	cpufunc_nullop,                 /* flush_brnchtgt_C     */
1092239268Sgonzo	(void *)cpufunc_nullop,         /* flush_brnchtgt_E     */
1093239268Sgonzo
1094239268Sgonzo	arm11_sleep,                    /* sleep                */
1095239268Sgonzo
1096239268Sgonzo	/* Soft functions */
1097239268Sgonzo
1098239268Sgonzo	cpufunc_null_fixup,             /* dataabt_fixup        */
1099239268Sgonzo	cpufunc_null_fixup,             /* prefetchabt_fixup    */
1100239268Sgonzo
1101245478Scognet	armv7_context_switch,           /* context_switch       */
1102239268Sgonzo
1103239268Sgonzo	cortexa_setup                     /* cpu setup            */
1104239268Sgonzo};
1105239268Sgonzo#endif /* CPU_CORTEXA */
1106201468Srpaulo
1107129198Scognet/*
1108129198Scognet * Global constants also used by locore.s
1109129198Scognet */
1110129198Scognet
1111129198Scognetstruct cpu_functions cpufuncs;
1112129198Scognetu_int cputype;
1113129198Scognetu_int cpu_reset_needs_v4_MMU_disable;	/* flag used in locore.s */
1114129198Scognet
1115207611Skevlo#if defined(CPU_ARM7TDMI) || defined(CPU_ARM8) || defined(CPU_ARM9) ||	\
1116244480Sgonzo  defined (CPU_ARM9E) || defined (CPU_ARM10) || defined (CPU_ARM1136) ||	\
1117244480Sgonzo  defined(CPU_ARM1176) || defined(CPU_XSCALE_80200) || defined(CPU_XSCALE_80321) ||		\
1118207611Skevlo  defined(CPU_XSCALE_PXA2X0) || defined(CPU_XSCALE_IXP425) ||		\
1119239268Sgonzo  defined(CPU_FA526) || defined(CPU_FA626TE) || defined(CPU_MV_PJ4B) ||			\
1120239268Sgonzo  defined(CPU_XSCALE_80219) || defined(CPU_XSCALE_81342) || \
1121259640Sganbold  defined(CPU_CORTEXA) || defined(CPU_KRAIT)
1122161592Scognet
1123137498Strhodesstatic void get_cachetype_cp15(void);
1124129198Scognet
1125129198Scognet/* Additional cache information local to this file.  Log2 of some of the
1126129198Scognet   above numbers.  */
1127129198Scognetstatic int	arm_dcache_l2_nsets;
1128129198Scognetstatic int	arm_dcache_l2_assoc;
1129129198Scognetstatic int	arm_dcache_l2_linesize;
1130129198Scognet
1131129198Scognetstatic void
1132129198Scognetget_cachetype_cp15()
1133129198Scognet{
1134239268Sgonzo	u_int ctype, isize, dsize, cpuid;
1135239268Sgonzo	u_int clevel, csize, i, sel;
1136129198Scognet	u_int multiplier;
1137239268Sgonzo	u_char type;
1138129198Scognet
1139129198Scognet	__asm __volatile("mrc p15, 0, %0, c0, c0, 1"
1140129198Scognet		: "=r" (ctype));
1141129198Scognet
1142239268Sgonzo	cpuid = cpufunc_id();
1143129198Scognet	/*
1144129198Scognet	 * ...and thus spake the ARM ARM:
1145129198Scognet	 *
1146129198Scognet	 * If an <opcode2> value corresponding to an unimplemented or
1147129198Scognet	 * reserved ID register is encountered, the System Control
1148129198Scognet	 * processor returns the value of the main ID register.
1149129198Scognet	 */
1150239268Sgonzo	if (ctype == cpuid)
1151129198Scognet		goto out;
1152129198Scognet
1153239268Sgonzo	if (CPU_CT_FORMAT(ctype) == CPU_CT_ARMV7) {
1154239268Sgonzo		__asm __volatile("mrc p15, 1, %0, c0, c0, 1"
1155239268Sgonzo		    : "=r" (clevel));
1156239268Sgonzo		arm_cache_level = clevel;
1157239268Sgonzo		arm_cache_loc = CPU_CLIDR_LOC(arm_cache_level);
1158239268Sgonzo		i = 0;
1159239268Sgonzo		while ((type = (clevel & 0x7)) && i < 7) {
1160239268Sgonzo			if (type == CACHE_DCACHE || type == CACHE_UNI_CACHE ||
1161239268Sgonzo			    type == CACHE_SEP_CACHE) {
1162239268Sgonzo				sel = i << 1;
1163239268Sgonzo				__asm __volatile("mcr p15, 2, %0, c0, c0, 0"
1164239268Sgonzo				    : : "r" (sel));
1165239268Sgonzo				__asm __volatile("mrc p15, 1, %0, c0, c0, 0"
1166239268Sgonzo				    : "=r" (csize));
1167239268Sgonzo				arm_cache_type[sel] = csize;
1168239268Sgonzo				arm_dcache_align = 1 <<
1169239268Sgonzo				    (CPUV7_CT_xSIZE_LEN(csize) + 4);
1170239268Sgonzo				arm_dcache_align_mask = arm_dcache_align - 1;
1171239268Sgonzo			}
1172239268Sgonzo			if (type == CACHE_ICACHE || type == CACHE_SEP_CACHE) {
1173239268Sgonzo				sel = (i << 1) | 1;
1174239268Sgonzo				__asm __volatile("mcr p15, 2, %0, c0, c0, 0"
1175239268Sgonzo				    : : "r" (sel));
1176239268Sgonzo				__asm __volatile("mrc p15, 1, %0, c0, c0, 0"
1177239268Sgonzo				    : "=r" (csize));
1178239268Sgonzo				arm_cache_type[sel] = csize;
1179239268Sgonzo			}
1180239268Sgonzo			i++;
1181239268Sgonzo			clevel >>= 3;
1182239268Sgonzo		}
1183239268Sgonzo	} else {
1184239268Sgonzo		if ((ctype & CPU_CT_S) == 0)
1185239268Sgonzo			arm_pcache_unified = 1;
1186129198Scognet
1187239268Sgonzo		/*
1188239268Sgonzo		 * If you want to know how this code works, go read the ARM ARM.
1189239268Sgonzo		 */
1190129198Scognet
1191239268Sgonzo		arm_pcache_type = CPU_CT_CTYPE(ctype);
1192129198Scognet
1193239268Sgonzo		if (arm_pcache_unified == 0) {
1194239268Sgonzo			isize = CPU_CT_ISIZE(ctype);
1195239268Sgonzo			multiplier = (isize & CPU_CT_xSIZE_M) ? 3 : 2;
1196239268Sgonzo			arm_picache_line_size = 1U << (CPU_CT_xSIZE_LEN(isize) + 3);
1197239268Sgonzo			if (CPU_CT_xSIZE_ASSOC(isize) == 0) {
1198239268Sgonzo				if (isize & CPU_CT_xSIZE_M)
1199239268Sgonzo					arm_picache_line_size = 0; /* not present */
1200239268Sgonzo				else
1201239268Sgonzo					arm_picache_ways = 1;
1202239268Sgonzo			} else {
1203239268Sgonzo				arm_picache_ways = multiplier <<
1204239268Sgonzo				    (CPU_CT_xSIZE_ASSOC(isize) - 1);
1205239268Sgonzo			}
1206239268Sgonzo			arm_picache_size = multiplier << (CPU_CT_xSIZE_SIZE(isize) + 8);
1207239268Sgonzo		}
1208239268Sgonzo
1209239268Sgonzo		dsize = CPU_CT_DSIZE(ctype);
1210239268Sgonzo		multiplier = (dsize & CPU_CT_xSIZE_M) ? 3 : 2;
1211239268Sgonzo		arm_pdcache_line_size = 1U << (CPU_CT_xSIZE_LEN(dsize) + 3);
1212239268Sgonzo		if (CPU_CT_xSIZE_ASSOC(dsize) == 0) {
1213239268Sgonzo			if (dsize & CPU_CT_xSIZE_M)
1214239268Sgonzo				arm_pdcache_line_size = 0; /* not present */
1215129198Scognet			else
1216239268Sgonzo				arm_pdcache_ways = 1;
1217129198Scognet		} else {
1218239268Sgonzo			arm_pdcache_ways = multiplier <<
1219239268Sgonzo			    (CPU_CT_xSIZE_ASSOC(dsize) - 1);
1220129198Scognet		}
1221239268Sgonzo		arm_pdcache_size = multiplier << (CPU_CT_xSIZE_SIZE(dsize) + 8);
1222129198Scognet
1223239268Sgonzo		arm_dcache_align = arm_pdcache_line_size;
1224129198Scognet
1225239268Sgonzo		arm_dcache_l2_assoc = CPU_CT_xSIZE_ASSOC(dsize) + multiplier - 2;
1226239268Sgonzo		arm_dcache_l2_linesize = CPU_CT_xSIZE_LEN(dsize) + 3;
1227239268Sgonzo		arm_dcache_l2_nsets = 6 + CPU_CT_xSIZE_SIZE(dsize) -
1228239268Sgonzo		    CPU_CT_xSIZE_ASSOC(dsize) - CPU_CT_xSIZE_LEN(dsize);
1229129198Scognet
1230239268Sgonzo	out:
1231239268Sgonzo		arm_dcache_align_mask = arm_dcache_align - 1;
1232239268Sgonzo	}
1233129198Scognet}
1234129198Scognet#endif /* ARM7TDMI || ARM8 || ARM9 || XSCALE */
1235129198Scognet
1236146619Scognet#if defined(CPU_SA110) || defined(CPU_SA1100) || defined(CPU_SA1110) || \
1237146619Scognet    defined(CPU_IXP12X0)
1238129198Scognet/* Cache information for CPUs without cache type registers. */
1239129198Scognetstruct cachetab {
1240129198Scognet	u_int32_t ct_cpuid;
1241129198Scognet	int	ct_pcache_type;
1242129198Scognet	int	ct_pcache_unified;
1243129198Scognet	int	ct_pdcache_size;
1244129198Scognet	int	ct_pdcache_line_size;
1245129198Scognet	int	ct_pdcache_ways;
1246129198Scognet	int	ct_picache_size;
1247129198Scognet	int	ct_picache_line_size;
1248129198Scognet	int	ct_picache_ways;
1249129198Scognet};
1250129198Scognet
1251129198Scognetstruct cachetab cachetab[] = {
1252129198Scognet    /* cpuid,           cache type,       u,  dsiz, ls, wy,  isiz, ls, wy */
1253129198Scognet    /* XXX is this type right for SA-1? */
1254129198Scognet    { CPU_ID_SA110,	CPU_CT_CTYPE_WB1, 0, 16384, 32, 32, 16384, 32, 32 },
1255129198Scognet    { CPU_ID_SA1100,	CPU_CT_CTYPE_WB1, 0,  8192, 32, 32, 16384, 32, 32 },
1256129198Scognet    { CPU_ID_SA1110,	CPU_CT_CTYPE_WB1, 0,  8192, 32, 32, 16384, 32, 32 },
1257129198Scognet    { CPU_ID_IXP1200,	CPU_CT_CTYPE_WB1, 0, 16384, 32, 32, 16384, 32, 32 }, /* XXX */
1258129198Scognet    { 0, 0, 0, 0, 0, 0, 0, 0}
1259129198Scognet};
1260129198Scognet
1261137498Strhodesstatic void get_cachetype_table(void);
1262129198Scognet
1263129198Scognetstatic void
1264129198Scognetget_cachetype_table()
1265129198Scognet{
1266129198Scognet	int i;
1267129198Scognet	u_int32_t cpuid = cpufunc_id();
1268129198Scognet
1269129198Scognet	for (i = 0; cachetab[i].ct_cpuid != 0; i++) {
1270129198Scognet		if (cachetab[i].ct_cpuid == (cpuid & CPU_ID_CPU_MASK)) {
1271129198Scognet			arm_pcache_type = cachetab[i].ct_pcache_type;
1272129198Scognet			arm_pcache_unified = cachetab[i].ct_pcache_unified;
1273129198Scognet			arm_pdcache_size = cachetab[i].ct_pdcache_size;
1274129198Scognet			arm_pdcache_line_size =
1275129198Scognet			    cachetab[i].ct_pdcache_line_size;
1276129198Scognet			arm_pdcache_ways = cachetab[i].ct_pdcache_ways;
1277129198Scognet			arm_picache_size = cachetab[i].ct_picache_size;
1278129198Scognet			arm_picache_line_size =
1279129198Scognet			    cachetab[i].ct_picache_line_size;
1280129198Scognet			arm_picache_ways = cachetab[i].ct_picache_ways;
1281129198Scognet		}
1282129198Scognet	}
1283129198Scognet	arm_dcache_align = arm_pdcache_line_size;
1284129198Scognet
1285129198Scognet	arm_dcache_align_mask = arm_dcache_align - 1;
1286129198Scognet}
1287129198Scognet
1288146619Scognet#endif /* SA110 || SA1100 || SA1111 || IXP12X0 */
1289129198Scognet
1290129198Scognet/*
1291129198Scognet * Cannot panic here as we may not have a console yet ...
1292129198Scognet */
1293129198Scognet
1294129198Scognetint
1295129198Scognetset_cpufuncs()
1296129198Scognet{
1297129198Scognet	cputype = cpufunc_id();
1298129198Scognet	cputype &= CPU_ID_CPU_MASK;
1299129198Scognet
1300129198Scognet	/*
1301129198Scognet	 * NOTE: cpu_do_powersave defaults to off.  If we encounter a
1302129198Scognet	 * CPU type where we want to use it by default, then we set it.
1303129198Scognet	 */
1304129198Scognet
1305129198Scognet#ifdef CPU_ARM7TDMI
1306129198Scognet	if ((cputype & CPU_ID_IMPLEMENTOR_MASK) == CPU_ID_ARM_LTD &&
1307129198Scognet	    CPU_ID_IS7(cputype) &&
1308129198Scognet	    (cputype & CPU_ID_7ARCH_MASK) == CPU_ID_7ARCH_V4T) {
1309129198Scognet		cpufuncs = arm7tdmi_cpufuncs;
1310129198Scognet		cpu_reset_needs_v4_MMU_disable = 0;
1311129198Scognet		get_cachetype_cp15();
1312129198Scognet		pmap_pte_init_generic();
1313166655Scognet		goto out;
1314129198Scognet	}
1315129198Scognet#endif
1316129198Scognet#ifdef CPU_ARM8
1317129198Scognet	if ((cputype & CPU_ID_IMPLEMENTOR_MASK) == CPU_ID_ARM_LTD &&
1318129198Scognet	    (cputype & 0x0000f000) == 0x00008000) {
1319129198Scognet		cpufuncs = arm8_cpufuncs;
1320129198Scognet		cpu_reset_needs_v4_MMU_disable = 0;	/* XXX correct? */
1321129198Scognet		get_cachetype_cp15();
1322129198Scognet		pmap_pte_init_arm8();
1323166655Scognet		goto out;
1324129198Scognet	}
1325129198Scognet#endif	/* CPU_ARM8 */
1326129198Scognet#ifdef CPU_ARM9
1327129198Scognet	if (((cputype & CPU_ID_IMPLEMENTOR_MASK) == CPU_ID_ARM_LTD ||
1328129198Scognet	     (cputype & CPU_ID_IMPLEMENTOR_MASK) == CPU_ID_TI) &&
1329129198Scognet	    (cputype & 0x0000f000) == 0x00009000) {
1330129198Scognet		cpufuncs = arm9_cpufuncs;
1331129198Scognet		cpu_reset_needs_v4_MMU_disable = 1;	/* V4 or higher */
1332129198Scognet		get_cachetype_cp15();
1333146605Scognet		arm9_dcache_sets_inc = 1U << arm_dcache_l2_linesize;
1334146605Scognet		arm9_dcache_sets_max = (1U << (arm_dcache_l2_linesize +
1335146605Scognet		    arm_dcache_l2_nsets)) - arm9_dcache_sets_inc;
1336146605Scognet		arm9_dcache_index_inc = 1U << (32 - arm_dcache_l2_assoc);
1337146605Scognet		arm9_dcache_index_max = 0U - arm9_dcache_index_inc;
1338137270Scognet#ifdef ARM9_CACHE_WRITE_THROUGH
1339129198Scognet		pmap_pte_init_arm9();
1340137270Scognet#else
1341137270Scognet		pmap_pte_init_generic();
1342137270Scognet#endif
1343166655Scognet		goto out;
1344129198Scognet	}
1345129198Scognet#endif /* CPU_ARM9 */
1346172738Simp#if defined(CPU_ARM9E) || defined(CPU_ARM10)
1347239268Sgonzo	if (cputype == CPU_ID_MV88FR131 || cputype == CPU_ID_MV88FR571_VD ||
1348183835Sraj	    cputype == CPU_ID_MV88FR571_41) {
1349239268Sgonzo		uint32_t sheeva_ctrl;
1350183835Sraj
1351239268Sgonzo		sheeva_ctrl = (MV_DC_STREAM_ENABLE | MV_BTB_DISABLE |
1352239268Sgonzo		    MV_L2_ENABLE);
1353239268Sgonzo		/*
1354239268Sgonzo		 * Workaround for Marvell MV78100 CPU: Cache prefetch
1355239268Sgonzo		 * mechanism may affect the cache coherency validity,
1356239268Sgonzo		 * so it needs to be disabled.
1357239268Sgonzo		 *
1358239268Sgonzo		 * Refer to errata document MV-S501058-00C.pdf (p. 3.1
1359239268Sgonzo		 * L2 Prefetching Mechanism) for details.
1360239268Sgonzo		 */
1361239268Sgonzo		if (cputype == CPU_ID_MV88FR571_VD ||
1362239268Sgonzo		    cputype == CPU_ID_MV88FR571_41)
1363239268Sgonzo			sheeva_ctrl |= MV_L2_PREFETCH_DISABLE;
1364212825Smav
1365239268Sgonzo		sheeva_control_ext(0xffffffff & ~MV_WA_ENABLE, sheeva_ctrl);
1366183835Sraj
1367239268Sgonzo		cpufuncs = sheeva_cpufuncs;
1368172738Simp		get_cachetype_cp15();
1369172738Simp		pmap_pte_init_generic();
1370174058Scognet		goto out;
1371239268Sgonzo	} else if (cputype == CPU_ID_ARM926EJS || cputype == CPU_ID_ARM1026EJS) {
1372239268Sgonzo		cpufuncs = armv5_ec_cpufuncs;
1373239268Sgonzo		get_cachetype_cp15();
1374239268Sgonzo		pmap_pte_init_generic();
1375239268Sgonzo		goto out;
1376172738Simp	}
1377172738Simp#endif /* CPU_ARM9E || CPU_ARM10 */
1378129198Scognet#ifdef CPU_ARM10
1379129198Scognet	if (/* cputype == CPU_ID_ARM1020T || */
1380129198Scognet	    cputype == CPU_ID_ARM1020E) {
1381129198Scognet		/*
1382129198Scognet		 * Select write-through cacheing (this isn't really an
1383129198Scognet		 * option on ARM1020T).
1384129198Scognet		 */
1385129198Scognet		cpufuncs = arm10_cpufuncs;
1386129198Scognet		cpu_reset_needs_v4_MMU_disable = 1;	/* V4 or higher */
1387129198Scognet		get_cachetype_cp15();
1388129198Scognet		arm10_dcache_sets_inc = 1U << arm_dcache_l2_linesize;
1389236991Simp		arm10_dcache_sets_max =
1390129198Scognet		    (1U << (arm_dcache_l2_linesize + arm_dcache_l2_nsets)) -
1391129198Scognet		    arm10_dcache_sets_inc;
1392129198Scognet		arm10_dcache_index_inc = 1U << (32 - arm_dcache_l2_assoc);
1393129198Scognet		arm10_dcache_index_max = 0U - arm10_dcache_index_inc;
1394129198Scognet		pmap_pte_init_generic();
1395166655Scognet		goto out;
1396129198Scognet	}
1397129198Scognet#endif /* CPU_ARM10 */
1398244480Sgonzo#if defined(CPU_ARM1136) || defined(CPU_ARM1176)
1399244480Sgonzo	if (cputype == CPU_ID_ARM1136JS
1400244480Sgonzo	    || cputype == CPU_ID_ARM1136JSR1
1401244480Sgonzo	    || cputype == CPU_ID_ARM1176JZS) {
1402244480Sgonzo#ifdef CPU_ARM1136
1403244480Sgonzo		if (cputype == CPU_ID_ARM1136JS
1404244480Sgonzo		    || cputype == CPU_ID_ARM1136JSR1)
1405244480Sgonzo			cpufuncs = arm1136_cpufuncs;
1406244480Sgonzo#endif
1407244480Sgonzo#ifdef CPU_ARM1176
1408244480Sgonzo		if (cputype == CPU_ID_ARM1176JZS)
1409244480Sgonzo			cpufuncs = arm1176_cpufuncs;
1410244480Sgonzo#endif
1411244480Sgonzo		cpu_reset_needs_v4_MMU_disable = 1;     /* V4 or higher */
1412244480Sgonzo		get_cachetype_cp15();
1413239701Sgonzo
1414244480Sgonzo		pmap_pte_init_mmu_v6();
1415244480Sgonzo
1416244480Sgonzo		goto out;
1417244480Sgonzo	}
1418244480Sgonzo#endif /* CPU_ARM1136 || CPU_ARM1176 */
1419259640Sganbold#if defined(CPU_CORTEXA) || defined(CPU_KRAIT)
1420256629Sbr	if (cputype == CPU_ID_CORTEXA5 ||
1421256629Sbr	    cputype == CPU_ID_CORTEXA7 ||
1422253857Sganbold	    cputype == CPU_ID_CORTEXA8R1 ||
1423239268Sgonzo	    cputype == CPU_ID_CORTEXA8R2 ||
1424239268Sgonzo	    cputype == CPU_ID_CORTEXA8R3 ||
1425239268Sgonzo	    cputype == CPU_ID_CORTEXA9R1 ||
1426249999Swkoszek	    cputype == CPU_ID_CORTEXA9R2 ||
1427252361Sray	    cputype == CPU_ID_CORTEXA9R3 ||
1428259640Sganbold	    cputype == CPU_ID_CORTEXA15 ||
1429259640Sganbold	    cputype == CPU_ID_KRAIT ) {
1430239268Sgonzo		cpufuncs = cortexa_cpufuncs;
1431239268Sgonzo		cpu_reset_needs_v4_MMU_disable = 1;     /* V4 or higher */
1432239268Sgonzo		get_cachetype_cp15();
1433239268Sgonzo
1434239268Sgonzo		pmap_pte_init_mmu_v6();
1435239268Sgonzo		/* Use powersave on this CPU. */
1436239268Sgonzo		cpu_do_powersave = 1;
1437239268Sgonzo		goto out;
1438239268Sgonzo	}
1439239268Sgonzo#endif /* CPU_CORTEXA */
1440239268Sgonzo
1441239268Sgonzo#if defined(CPU_MV_PJ4B)
1442257281Szbb	if (cputype == CPU_ID_MV88SV581X_V7 ||
1443240486Sgber	    cputype == CPU_ID_MV88SV584X_V7 ||
1444239268Sgonzo	    cputype == CPU_ID_ARM_88SV581X_V7) {
1445257281Szbb		cpufuncs = pj4bv7_cpufuncs;
1446239268Sgonzo		get_cachetype_cp15();
1447239268Sgonzo		pmap_pte_init_mmu_v6();
1448239268Sgonzo		goto out;
1449239268Sgonzo	}
1450239268Sgonzo#endif /* CPU_MV_PJ4B */
1451129198Scognet#ifdef CPU_SA110
1452129198Scognet	if (cputype == CPU_ID_SA110) {
1453129198Scognet		cpufuncs = sa110_cpufuncs;
1454129198Scognet		cpu_reset_needs_v4_MMU_disable = 1;	/* SA needs it */
1455129198Scognet		get_cachetype_table();
1456129198Scognet		pmap_pte_init_sa1();
1457166655Scognet		goto out;
1458129198Scognet	}
1459129198Scognet#endif	/* CPU_SA110 */
1460129198Scognet#ifdef CPU_SA1100
1461129198Scognet	if (cputype == CPU_ID_SA1100) {
1462129198Scognet		cpufuncs = sa11x0_cpufuncs;
1463129198Scognet		cpu_reset_needs_v4_MMU_disable = 1;	/* SA needs it	*/
1464129198Scognet		get_cachetype_table();
1465129198Scognet		pmap_pte_init_sa1();
1466129198Scognet		/* Use powersave on this CPU. */
1467129198Scognet		cpu_do_powersave = 1;
1468129198Scognet
1469166655Scognet		goto out;
1470129198Scognet	}
1471129198Scognet#endif	/* CPU_SA1100 */
1472129198Scognet#ifdef CPU_SA1110
1473129198Scognet	if (cputype == CPU_ID_SA1110) {
1474129198Scognet		cpufuncs = sa11x0_cpufuncs;
1475129198Scognet		cpu_reset_needs_v4_MMU_disable = 1;	/* SA needs it	*/
1476129198Scognet		get_cachetype_table();
1477129198Scognet		pmap_pte_init_sa1();
1478129198Scognet		/* Use powersave on this CPU. */
1479129198Scognet		cpu_do_powersave = 1;
1480129198Scognet
1481166655Scognet		goto out;
1482129198Scognet	}
1483129198Scognet#endif	/* CPU_SA1110 */
1484207611Skevlo#if defined(CPU_FA526) || defined(CPU_FA626TE)
1485207611Skevlo	if (cputype == CPU_ID_FA526 || cputype == CPU_ID_FA626TE) {
1486201468Srpaulo		cpufuncs = fa526_cpufuncs;
1487201468Srpaulo		cpu_reset_needs_v4_MMU_disable = 1;	/* SA needs it	*/
1488201468Srpaulo		get_cachetype_cp15();
1489201468Srpaulo		pmap_pte_init_generic();
1490201468Srpaulo
1491201468Srpaulo		/* Use powersave on this CPU. */
1492201468Srpaulo		cpu_do_powersave = 1;
1493201468Srpaulo
1494201468Srpaulo		goto out;
1495201468Srpaulo	}
1496207611Skevlo#endif	/* CPU_FA526 || CPU_FA626TE */
1497129198Scognet#ifdef CPU_IXP12X0
1498129198Scognet        if (cputype == CPU_ID_IXP1200) {
1499129198Scognet                cpufuncs = ixp12x0_cpufuncs;
1500129198Scognet                cpu_reset_needs_v4_MMU_disable = 1;
1501129198Scognet                get_cachetype_table();
1502129198Scognet                pmap_pte_init_sa1();
1503166655Scognet		goto out;
1504129198Scognet        }
1505129198Scognet#endif  /* CPU_IXP12X0 */
1506129198Scognet#ifdef CPU_XSCALE_80200
1507129198Scognet	if (cputype == CPU_ID_80200) {
1508129198Scognet		int rev = cpufunc_id() & CPU_ID_REVISION_MASK;
1509129198Scognet
1510129198Scognet		i80200_icu_init();
1511129198Scognet
1512129198Scognet#if defined(XSCALE_CCLKCFG)
1513129198Scognet		/*
1514129198Scognet		 * Crank CCLKCFG to maximum legal value.
1515129198Scognet		 */
1516129198Scognet		__asm __volatile ("mcr p14, 0, %0, c6, c0, 0"
1517129198Scognet			:
1518129198Scognet			: "r" (XSCALE_CCLKCFG));
1519129198Scognet#endif
1520129198Scognet
1521129198Scognet		/*
1522129198Scognet		 * XXX Disable ECC in the Bus Controller Unit; we
1523129198Scognet		 * don't really support it, yet.  Clear any pending
1524129198Scognet		 * error indications.
1525129198Scognet		 */
1526129198Scognet		__asm __volatile("mcr p13, 0, %0, c0, c1, 0"
1527129198Scognet			:
1528129198Scognet			: "r" (BCUCTL_E0|BCUCTL_E1|BCUCTL_EV));
1529129198Scognet
1530129198Scognet		cpufuncs = xscale_cpufuncs;
1531129198Scognet		/*
1532129198Scognet		 * i80200 errata: Step-A0 and A1 have a bug where
1533129198Scognet		 * D$ dirty bits are not cleared on "invalidate by
1534129198Scognet		 * address".
1535129198Scognet		 *
1536129198Scognet		 * Workaround: Clean cache line before invalidating.
1537129198Scognet		 */
1538129198Scognet		if (rev == 0 || rev == 1)
1539129198Scognet			cpufuncs.cf_dcache_inv_range = xscale_cache_purgeD_rng;
1540129198Scognet
1541129198Scognet		cpu_reset_needs_v4_MMU_disable = 1;	/* XScale needs it */
1542129198Scognet		get_cachetype_cp15();
1543129198Scognet		pmap_pte_init_xscale();
1544166655Scognet		goto out;
1545129198Scognet	}
1546129198Scognet#endif /* CPU_XSCALE_80200 */
1547161592Scognet#if defined(CPU_XSCALE_80321) || defined(CPU_XSCALE_80219)
1548129198Scognet	if (cputype == CPU_ID_80321_400 || cputype == CPU_ID_80321_600 ||
1549161592Scognet	    cputype == CPU_ID_80321_400_B0 || cputype == CPU_ID_80321_600_B0 ||
1550161592Scognet	    cputype == CPU_ID_80219_400 || cputype == CPU_ID_80219_600) {
1551129198Scognet		cpufuncs = xscale_cpufuncs;
1552129198Scognet		cpu_reset_needs_v4_MMU_disable = 1;	/* XScale needs it */
1553129198Scognet		get_cachetype_cp15();
1554129198Scognet		pmap_pte_init_xscale();
1555166655Scognet		goto out;
1556129198Scognet	}
1557129198Scognet#endif /* CPU_XSCALE_80321 */
1558161592Scognet
1559164080Scognet#if defined(CPU_XSCALE_81342)
1560164080Scognet	if (cputype == CPU_ID_81342) {
1561164080Scognet		cpufuncs = xscalec3_cpufuncs;
1562164080Scognet		cpu_reset_needs_v4_MMU_disable = 1;	/* XScale needs it */
1563164080Scognet		get_cachetype_cp15();
1564164080Scognet		pmap_pte_init_xscale();
1565166655Scognet		goto out;
1566164080Scognet	}
1567164080Scognet#endif /* CPU_XSCALE_81342 */
1568129198Scognet#ifdef CPU_XSCALE_PXA2X0
1569129198Scognet	/* ignore core revision to test PXA2xx CPUs */
1570129198Scognet	if ((cputype & ~CPU_ID_XSCALE_COREREV_MASK) == CPU_ID_PXA250 ||
1571191817Sstas	    (cputype & ~CPU_ID_XSCALE_COREREV_MASK) == CPU_ID_PXA27X ||
1572129198Scognet	    (cputype & ~CPU_ID_XSCALE_COREREV_MASK) == CPU_ID_PXA210) {
1573129198Scognet
1574129198Scognet		cpufuncs = xscale_cpufuncs;
1575129198Scognet		cpu_reset_needs_v4_MMU_disable = 1;	/* XScale needs it */
1576129198Scognet		get_cachetype_cp15();
1577129198Scognet		pmap_pte_init_xscale();
1578129198Scognet
1579129198Scognet		/* Use powersave on this CPU. */
1580129198Scognet		cpu_do_powersave = 1;
1581129198Scognet
1582166655Scognet		goto out;
1583129198Scognet	}
1584129198Scognet#endif /* CPU_XSCALE_PXA2X0 */
1585129198Scognet#ifdef CPU_XSCALE_IXP425
1586129198Scognet	if (cputype == CPU_ID_IXP425_533 || cputype == CPU_ID_IXP425_400 ||
1587186352Ssam            cputype == CPU_ID_IXP425_266 || cputype == CPU_ID_IXP435) {
1588129198Scognet
1589129198Scognet		cpufuncs = xscale_cpufuncs;
1590129198Scognet		cpu_reset_needs_v4_MMU_disable = 1;	/* XScale needs it */
1591129198Scognet		get_cachetype_cp15();
1592129198Scognet		pmap_pte_init_xscale();
1593129198Scognet
1594166655Scognet		goto out;
1595129198Scognet	}
1596129198Scognet#endif /* CPU_XSCALE_IXP425 */
1597129198Scognet	/*
1598129198Scognet	 * Bzzzz. And the answer was ...
1599129198Scognet	 */
1600129198Scognet	panic("No support for this CPU type (%08x) in kernel", cputype);
1601129198Scognet	return(ARCHITECTURE_NOT_PRESENT);
1602166655Scognetout:
1603166655Scognet	uma_set_align(arm_dcache_align_mask);
1604166655Scognet	return (0);
1605129198Scognet}
1606129198Scognet
1607129198Scognet/*
1608129198Scognet * Fixup routines for data and prefetch aborts.
1609129198Scognet *
1610129198Scognet * Several compile time symbols are used
1611129198Scognet *
1612129198Scognet * DEBUG_FAULT_CORRECTION - Print debugging information during the
1613129198Scognet * correction of registers after a fault.
1614129198Scognet * ARM6_LATE_ABORT - ARM6 supports both early and late aborts
1615129198Scognet * when defined should use late aborts
1616129198Scognet */
1617129198Scognet
1618129198Scognet
1619129198Scognet/*
1620129198Scognet * Null abort fixup routine.
1621129198Scognet * For use when no fixup is required.
1622129198Scognet */
1623129198Scognetint
1624129198Scognetcpufunc_null_fixup(arg)
1625129198Scognet	void *arg;
1626129198Scognet{
1627129198Scognet	return(ABORT_FIXUP_OK);
1628129198Scognet}
1629129198Scognet
1630129198Scognet
1631146619Scognet#if defined(CPU_ARM7TDMI)
1632129198Scognet
1633129198Scognet#ifdef DEBUG_FAULT_CORRECTION
1634129198Scognet#define DFC_PRINTF(x)		printf x
1635129198Scognet#define DFC_DISASSEMBLE(x)	disassemble(x)
1636129198Scognet#else
1637129198Scognet#define DFC_PRINTF(x)		/* nothing */
1638129198Scognet#define DFC_DISASSEMBLE(x)	/* nothing */
1639129198Scognet#endif
1640129198Scognet
1641129198Scognet/*
1642129198Scognet * "Early" data abort fixup.
1643129198Scognet *
1644129198Scognet * For ARM2, ARM2as, ARM3 and ARM6 (in early-abort mode).  Also used
1645129198Scognet * indirectly by ARM6 (in late-abort mode) and ARM7[TDMI].
1646129198Scognet *
1647129198Scognet * In early aborts, we may have to fix up LDM, STM, LDC and STC.
1648129198Scognet */
1649129198Scognetint
1650129198Scognetearly_abort_fixup(arg)
1651129198Scognet	void *arg;
1652129198Scognet{
1653257217Sian	struct trapframe *frame = arg;
1654129198Scognet	u_int fault_pc;
1655129198Scognet	u_int fault_instruction;
1656129198Scognet	int saved_lr = 0;
1657129198Scognet
1658129198Scognet	if ((frame->tf_spsr & PSR_MODE) == PSR_SVC32_MODE) {
1659129198Scognet
1660129198Scognet		/* Ok an abort in SVC mode */
1661129198Scognet
1662129198Scognet		/*
1663129198Scognet		 * Copy the SVC r14 into the usr r14 - The usr r14 is garbage
1664129198Scognet		 * as the fault happened in svc mode but we need it in the
1665129198Scognet		 * usr slot so we can treat the registers as an array of ints
1666129198Scognet		 * during fixing.
1667129198Scognet		 * NOTE: This PC is in the position but writeback is not
1668129198Scognet		 * allowed on r15.
1669129198Scognet		 * Doing it like this is more efficient than trapping this
1670129198Scognet		 * case in all possible locations in the following fixup code.
1671129198Scognet		 */
1672129198Scognet
1673129198Scognet		saved_lr = frame->tf_usr_lr;
1674129198Scognet		frame->tf_usr_lr = frame->tf_svc_lr;
1675129198Scognet
1676129198Scognet		/*
1677129198Scognet		 * Note the trapframe does not have the SVC r13 so a fault
1678129198Scognet		 * from an instruction with writeback to r13 in SVC mode is
1679129198Scognet		 * not allowed. This should not happen as the kstack is
1680129198Scognet		 * always valid.
1681129198Scognet		 */
1682129198Scognet	}
1683129198Scognet
1684129198Scognet	/* Get fault address and status from the CPU */
1685129198Scognet
1686129198Scognet	fault_pc = frame->tf_pc;
1687129198Scognet	fault_instruction = *((volatile unsigned int *)fault_pc);
1688129198Scognet
1689129198Scognet	/* Decode the fault instruction and fix the registers as needed */
1690129198Scognet
1691129198Scognet	if ((fault_instruction & 0x0e000000) == 0x08000000) {
1692129198Scognet		int base;
1693129198Scognet		int loop;
1694129198Scognet		int count;
1695129198Scognet		int *registers = &frame->tf_r0;
1696236991Simp
1697129198Scognet		DFC_PRINTF(("LDM/STM\n"));
1698129198Scognet		DFC_DISASSEMBLE(fault_pc);
1699129198Scognet		if (fault_instruction & (1 << 21)) {
1700129198Scognet			DFC_PRINTF(("This instruction must be corrected\n"));
1701129198Scognet			base = (fault_instruction >> 16) & 0x0f;
1702129198Scognet			if (base == 15)
1703129198Scognet				return ABORT_FIXUP_FAILED;
1704129198Scognet			/* Count registers transferred */
1705129198Scognet			count = 0;
1706129198Scognet			for (loop = 0; loop < 16; ++loop) {
1707129198Scognet				if (fault_instruction & (1<<loop))
1708129198Scognet					++count;
1709129198Scognet			}
1710129198Scognet			DFC_PRINTF(("%d registers used\n", count));
1711129198Scognet			DFC_PRINTF(("Corrected r%d by %d bytes ",
1712129198Scognet				       base, count * 4));
1713129198Scognet			if (fault_instruction & (1 << 23)) {
1714129198Scognet				DFC_PRINTF(("down\n"));
1715129198Scognet				registers[base] -= count * 4;
1716129198Scognet			} else {
1717129198Scognet				DFC_PRINTF(("up\n"));
1718129198Scognet				registers[base] += count * 4;
1719129198Scognet			}
1720129198Scognet		}
1721129198Scognet	} else if ((fault_instruction & 0x0e000000) == 0x0c000000) {
1722129198Scognet		int base;
1723129198Scognet		int offset;
1724129198Scognet		int *registers = &frame->tf_r0;
1725129198Scognet
1726129198Scognet		/* REGISTER CORRECTION IS REQUIRED FOR THESE INSTRUCTIONS */
1727129198Scognet
1728129198Scognet		DFC_DISASSEMBLE(fault_pc);
1729129198Scognet
1730129198Scognet		/* Only need to fix registers if write back is turned on */
1731129198Scognet
1732129198Scognet		if ((fault_instruction & (1 << 21)) != 0) {
1733129198Scognet			base = (fault_instruction >> 16) & 0x0f;
1734129198Scognet			if (base == 13 &&
1735129198Scognet			    (frame->tf_spsr & PSR_MODE) == PSR_SVC32_MODE)
1736129198Scognet				return ABORT_FIXUP_FAILED;
1737129198Scognet			if (base == 15)
1738129198Scognet				return ABORT_FIXUP_FAILED;
1739129198Scognet
1740129198Scognet			offset = (fault_instruction & 0xff) << 2;
1741129198Scognet			DFC_PRINTF(("r%d=%08x\n", base, registers[base]));
1742129198Scognet			if ((fault_instruction & (1 << 23)) != 0)
1743129198Scognet				offset = -offset;
1744129198Scognet			registers[base] += offset;
1745129198Scognet			DFC_PRINTF(("r%d=%08x\n", base, registers[base]));
1746129198Scognet		}
1747129198Scognet	} else if ((fault_instruction & 0x0e000000) == 0x0c000000)
1748129198Scognet		return ABORT_FIXUP_FAILED;
1749129198Scognet
1750129198Scognet	if ((frame->tf_spsr & PSR_MODE) == PSR_SVC32_MODE) {
1751129198Scognet
1752129198Scognet		/* Ok an abort in SVC mode */
1753129198Scognet
1754129198Scognet		/*
1755129198Scognet		 * Copy the SVC r14 into the usr r14 - The usr r14 is garbage
1756129198Scognet		 * as the fault happened in svc mode but we need it in the
1757129198Scognet		 * usr slot so we can treat the registers as an array of ints
1758129198Scognet		 * during fixing.
1759129198Scognet		 * NOTE: This PC is in the position but writeback is not
1760129198Scognet		 * allowed on r15.
1761129198Scognet		 * Doing it like this is more efficient than trapping this
1762129198Scognet		 * case in all possible locations in the prior fixup code.
1763129198Scognet		 */
1764129198Scognet
1765129198Scognet		frame->tf_svc_lr = frame->tf_usr_lr;
1766129198Scognet		frame->tf_usr_lr = saved_lr;
1767129198Scognet
1768129198Scognet		/*
1769129198Scognet		 * Note the trapframe does not have the SVC r13 so a fault
1770129198Scognet		 * from an instruction with writeback to r13 in SVC mode is
1771129198Scognet		 * not allowed. This should not happen as the kstack is
1772129198Scognet		 * always valid.
1773129198Scognet		 */
1774129198Scognet	}
1775129198Scognet
1776129198Scognet	return(ABORT_FIXUP_OK);
1777129198Scognet}
1778129198Scognet#endif	/* CPU_ARM2/250/3/6/7 */
1779129198Scognet
1780129198Scognet
1781146619Scognet#if defined(CPU_ARM7TDMI)
1782129198Scognet/*
1783129198Scognet * "Late" (base updated) data abort fixup
1784129198Scognet *
1785129198Scognet * For ARM6 (in late-abort mode) and ARM7.
1786129198Scognet *
1787129198Scognet * In this model, all data-transfer instructions need fixing up.  We defer
1788129198Scognet * LDM, STM, LDC and STC fixup to the early-abort handler.
1789129198Scognet */
1790129198Scognetint
1791129198Scognetlate_abort_fixup(arg)
1792129198Scognet	void *arg;
1793129198Scognet{
1794257217Sian	struct trapframe *frame = arg;
1795129198Scognet	u_int fault_pc;
1796129198Scognet	u_int fault_instruction;
1797129198Scognet	int saved_lr = 0;
1798129198Scognet
1799129198Scognet	if ((frame->tf_spsr & PSR_MODE) == PSR_SVC32_MODE) {
1800129198Scognet
1801129198Scognet		/* Ok an abort in SVC mode */
1802129198Scognet
1803129198Scognet		/*
1804129198Scognet		 * Copy the SVC r14 into the usr r14 - The usr r14 is garbage
1805129198Scognet		 * as the fault happened in svc mode but we need it in the
1806129198Scognet		 * usr slot so we can treat the registers as an array of ints
1807129198Scognet		 * during fixing.
1808129198Scognet		 * NOTE: This PC is in the position but writeback is not
1809129198Scognet		 * allowed on r15.
1810129198Scognet		 * Doing it like this is more efficient than trapping this
1811129198Scognet		 * case in all possible locations in the following fixup code.
1812129198Scognet		 */
1813129198Scognet
1814129198Scognet		saved_lr = frame->tf_usr_lr;
1815129198Scognet		frame->tf_usr_lr = frame->tf_svc_lr;
1816129198Scognet
1817129198Scognet		/*
1818129198Scognet		 * Note the trapframe does not have the SVC r13 so a fault
1819129198Scognet		 * from an instruction with writeback to r13 in SVC mode is
1820129198Scognet		 * not allowed. This should not happen as the kstack is
1821129198Scognet		 * always valid.
1822129198Scognet		 */
1823129198Scognet	}
1824129198Scognet
1825129198Scognet	/* Get fault address and status from the CPU */
1826129198Scognet
1827129198Scognet	fault_pc = frame->tf_pc;
1828129198Scognet	fault_instruction = *((volatile unsigned int *)fault_pc);
1829129198Scognet
1830129198Scognet	/* Decode the fault instruction and fix the registers as needed */
1831129198Scognet
1832129198Scognet	/* Was is a swap instruction ? */
1833129198Scognet
1834129198Scognet	if ((fault_instruction & 0x0fb00ff0) == 0x01000090) {
1835129198Scognet		DFC_DISASSEMBLE(fault_pc);
1836129198Scognet	} else if ((fault_instruction & 0x0c000000) == 0x04000000) {
1837129198Scognet
1838129198Scognet		/* Was is a ldr/str instruction */
1839129198Scognet		/* This is for late abort only */
1840129198Scognet
1841129198Scognet		int base;
1842129198Scognet		int offset;
1843129198Scognet		int *registers = &frame->tf_r0;
1844129198Scognet
1845129198Scognet		DFC_DISASSEMBLE(fault_pc);
1846129198Scognet
1847129198Scognet		/* This is for late abort only */
1848129198Scognet
1849129198Scognet		if ((fault_instruction & (1 << 24)) == 0
1850129198Scognet		    || (fault_instruction & (1 << 21)) != 0) {
1851129198Scognet			/* postindexed ldr/str with no writeback */
1852129198Scognet
1853129198Scognet			base = (fault_instruction >> 16) & 0x0f;
1854129198Scognet			if (base == 13 &&
1855129198Scognet			    (frame->tf_spsr & PSR_MODE) == PSR_SVC32_MODE)
1856129198Scognet				return ABORT_FIXUP_FAILED;
1857129198Scognet			if (base == 15)
1858129198Scognet				return ABORT_FIXUP_FAILED;
1859129198Scognet			DFC_PRINTF(("late abt fix: r%d=%08x : ",
1860129198Scognet				       base, registers[base]));
1861129198Scognet			if ((fault_instruction & (1 << 25)) == 0) {
1862129198Scognet				/* Immediate offset - easy */
1863129198Scognet
1864129198Scognet				offset = fault_instruction & 0xfff;
1865129198Scognet				if ((fault_instruction & (1 << 23)))
1866129198Scognet					offset = -offset;
1867129198Scognet				registers[base] += offset;
1868129198Scognet				DFC_PRINTF(("imm=%08x ", offset));
1869129198Scognet			} else {
1870129198Scognet				/* offset is a shifted register */
1871129198Scognet				int shift;
1872129198Scognet
1873129198Scognet				offset = fault_instruction & 0x0f;
1874129198Scognet				if (offset == base)
1875129198Scognet					return ABORT_FIXUP_FAILED;
1876236991Simp
1877129198Scognet				/*
1878129198Scognet				 * Register offset - hard we have to
1879129198Scognet				 * cope with shifts !
1880129198Scognet				 */
1881129198Scognet				offset = registers[offset];
1882129198Scognet
1883129198Scognet				if ((fault_instruction & (1 << 4)) == 0)
1884129198Scognet					/* shift with amount */
1885129198Scognet					shift = (fault_instruction >> 7) & 0x1f;
1886129198Scognet				else {
1887129198Scognet					/* shift with register */
1888129198Scognet					if ((fault_instruction & (1 << 7)) != 0)
1889129198Scognet						/* undefined for now so bail out */
1890129198Scognet						return ABORT_FIXUP_FAILED;
1891129198Scognet					shift = ((fault_instruction >> 8) & 0xf);
1892129198Scognet					if (base == shift)
1893129198Scognet						return ABORT_FIXUP_FAILED;
1894129198Scognet					DFC_PRINTF(("shift reg=%d ", shift));
1895129198Scognet					shift = registers[shift];
1896129198Scognet				}
1897129198Scognet				DFC_PRINTF(("shift=%08x ", shift));
1898129198Scognet				switch (((fault_instruction >> 5) & 0x3)) {
1899129198Scognet				case 0 : /* Logical left */
1900129198Scognet					offset = (int)(((u_int)offset) << shift);
1901129198Scognet					break;
1902129198Scognet				case 1 : /* Logical Right */
1903129198Scognet					if (shift == 0) shift = 32;
1904129198Scognet					offset = (int)(((u_int)offset) >> shift);
1905129198Scognet					break;
1906129198Scognet				case 2 : /* Arithmetic Right */
1907129198Scognet					if (shift == 0) shift = 32;
1908129198Scognet					offset = (int)(((int)offset) >> shift);
1909129198Scognet					break;
1910129198Scognet				case 3 : /* Rotate right (rol or rxx) */
1911129198Scognet					return ABORT_FIXUP_FAILED;
1912129198Scognet					break;
1913129198Scognet				}
1914129198Scognet
1915129198Scognet				DFC_PRINTF(("abt: fixed LDR/STR with "
1916129198Scognet					       "register offset\n"));
1917129198Scognet				if ((fault_instruction & (1 << 23)))
1918129198Scognet					offset = -offset;
1919129198Scognet				DFC_PRINTF(("offset=%08x ", offset));
1920129198Scognet				registers[base] += offset;
1921129198Scognet			}
1922129198Scognet			DFC_PRINTF(("r%d=%08x\n", base, registers[base]));
1923129198Scognet		}
1924129198Scognet	}
1925129198Scognet
1926129198Scognet	if ((frame->tf_spsr & PSR_MODE) == PSR_SVC32_MODE) {
1927129198Scognet
1928129198Scognet		/* Ok an abort in SVC mode */
1929129198Scognet
1930129198Scognet		/*
1931129198Scognet		 * Copy the SVC r14 into the usr r14 - The usr r14 is garbage
1932129198Scognet		 * as the fault happened in svc mode but we need it in the
1933129198Scognet		 * usr slot so we can treat the registers as an array of ints
1934129198Scognet		 * during fixing.
1935129198Scognet		 * NOTE: This PC is in the position but writeback is not
1936129198Scognet		 * allowed on r15.
1937129198Scognet		 * Doing it like this is more efficient than trapping this
1938129198Scognet		 * case in all possible locations in the prior fixup code.
1939129198Scognet		 */
1940129198Scognet
1941129198Scognet		frame->tf_svc_lr = frame->tf_usr_lr;
1942129198Scognet		frame->tf_usr_lr = saved_lr;
1943129198Scognet
1944129198Scognet		/*
1945129198Scognet		 * Note the trapframe does not have the SVC r13 so a fault
1946129198Scognet		 * from an instruction with writeback to r13 in SVC mode is
1947129198Scognet		 * not allowed. This should not happen as the kstack is
1948129198Scognet		 * always valid.
1949129198Scognet		 */
1950129198Scognet	}
1951129198Scognet
1952129198Scognet	/*
1953129198Scognet	 * Now let the early-abort fixup routine have a go, in case it
1954129198Scognet	 * was an LDM, STM, LDC or STC that faulted.
1955129198Scognet	 */
1956129198Scognet
1957129198Scognet	return early_abort_fixup(arg);
1958129198Scognet}
1959146619Scognet#endif	/* CPU_ARM7TDMI */
1960129198Scognet
1961129198Scognet/*
1962129198Scognet * CPU Setup code
1963129198Scognet */
1964129198Scognet
1965146619Scognet#if defined(CPU_ARM7TDMI) || defined(CPU_ARM8) || defined (CPU_ARM9) || \
1966172738Simp  defined(CPU_ARM9E) || \
1967161592Scognet  defined(CPU_SA110) || defined(CPU_SA1100) || defined(CPU_SA1110) ||	\
1968161592Scognet  defined(CPU_XSCALE_80200) || defined(CPU_XSCALE_80321) ||		\
1969161592Scognet  defined(CPU_XSCALE_PXA2X0) || defined(CPU_XSCALE_IXP425) ||		\
1970172738Simp  defined(CPU_XSCALE_80219) || defined(CPU_XSCALE_81342) || \
1971244480Sgonzo  defined(CPU_ARM10) ||  defined(CPU_ARM1136) || defined(CPU_ARM1176) ||\
1972207611Skevlo  defined(CPU_FA526) || defined(CPU_FA626TE)
1973129198Scognet
1974129198Scognet#define IGN	0
1975129198Scognet#define OR	1
1976129198Scognet#define BIC	2
1977129198Scognet
1978129198Scognetstruct cpu_option {
1979129198Scognet	char	*co_name;
1980129198Scognet	int	co_falseop;
1981129198Scognet	int	co_trueop;
1982129198Scognet	int	co_value;
1983129198Scognet};
1984129198Scognet
1985137498Strhodesstatic u_int parse_cpu_options(char *, struct cpu_option *, u_int);
1986129198Scognet
1987129198Scognetstatic u_int
1988129198Scognetparse_cpu_options(args, optlist, cpuctrl)
1989129198Scognet	char *args;
1990236991Simp	struct cpu_option *optlist;
1991236991Simp	u_int cpuctrl;
1992129198Scognet{
1993129198Scognet	int integer;
1994129198Scognet
1995129198Scognet	if (args == NULL)
1996129198Scognet		return(cpuctrl);
1997129198Scognet
1998129198Scognet	while (optlist->co_name) {
1999129198Scognet		if (get_bootconf_option(args, optlist->co_name,
2000129198Scognet		    BOOTOPT_TYPE_BOOLEAN, &integer)) {
2001129198Scognet			if (integer) {
2002129198Scognet				if (optlist->co_trueop == OR)
2003129198Scognet					cpuctrl |= optlist->co_value;
2004129198Scognet				else if (optlist->co_trueop == BIC)
2005129198Scognet					cpuctrl &= ~optlist->co_value;
2006129198Scognet			} else {
2007129198Scognet				if (optlist->co_falseop == OR)
2008129198Scognet					cpuctrl |= optlist->co_value;
2009129198Scognet				else if (optlist->co_falseop == BIC)
2010129198Scognet					cpuctrl &= ~optlist->co_value;
2011129198Scognet			}
2012129198Scognet		}
2013129198Scognet		++optlist;
2014129198Scognet	}
2015129198Scognet	return(cpuctrl);
2016129198Scognet}
2017161592Scognet#endif /* CPU_ARM7TDMI || CPU_ARM8 || CPU_SA110 || XSCALE*/
2018129198Scognet
2019146619Scognet#if defined(CPU_ARM7TDMI) || defined(CPU_ARM8)
2020129198Scognetstruct cpu_option arm678_options[] = {
2021129198Scognet#ifdef COMPAT_12
2022129198Scognet	{ "nocache",		IGN, BIC, CPU_CONTROL_IDC_ENABLE },
2023129198Scognet	{ "nowritebuf",		IGN, BIC, CPU_CONTROL_WBUF_ENABLE },
2024129198Scognet#endif	/* COMPAT_12 */
2025129198Scognet	{ "cpu.cache",		BIC, OR,  CPU_CONTROL_IDC_ENABLE },
2026129198Scognet	{ "cpu.nocache",	OR,  BIC, CPU_CONTROL_IDC_ENABLE },
2027129198Scognet	{ "cpu.writebuf",	BIC, OR,  CPU_CONTROL_WBUF_ENABLE },
2028129198Scognet	{ "cpu.nowritebuf",	OR,  BIC, CPU_CONTROL_WBUF_ENABLE },
2029129198Scognet	{ NULL,			IGN, IGN, 0 }
2030129198Scognet};
2031129198Scognet
2032129198Scognet#endif	/* CPU_ARM6 || CPU_ARM7 || CPU_ARM7TDMI || CPU_ARM8 */
2033129198Scognet
2034129198Scognet#ifdef CPU_ARM7TDMI
2035129198Scognetstruct cpu_option arm7tdmi_options[] = {
2036129198Scognet	{ "arm7.cache",		BIC, OR,  CPU_CONTROL_IDC_ENABLE },
2037129198Scognet	{ "arm7.nocache",	OR,  BIC, CPU_CONTROL_IDC_ENABLE },
2038129198Scognet	{ "arm7.writebuf",	BIC, OR,  CPU_CONTROL_WBUF_ENABLE },
2039129198Scognet	{ "arm7.nowritebuf",	OR,  BIC, CPU_CONTROL_WBUF_ENABLE },
2040129198Scognet#ifdef COMPAT_12
2041129198Scognet	{ "fpaclk2",		BIC, OR,  CPU_CONTROL_CPCLK },
2042129198Scognet#endif	/* COMPAT_12 */
2043129198Scognet	{ "arm700.fpaclk",	BIC, OR,  CPU_CONTROL_CPCLK },
2044129198Scognet	{ NULL,			IGN, IGN, 0 }
2045129198Scognet};
2046129198Scognet
2047129198Scognetvoid
2048129198Scognetarm7tdmi_setup(args)
2049129198Scognet	char *args;
2050129198Scognet{
2051129198Scognet	int cpuctrl;
2052129198Scognet
2053129198Scognet	cpuctrl = CPU_CONTROL_MMU_ENABLE | CPU_CONTROL_32BP_ENABLE
2054129198Scognet		 | CPU_CONTROL_32BD_ENABLE | CPU_CONTROL_SYST_ENABLE
2055129198Scognet		 | CPU_CONTROL_IDC_ENABLE | CPU_CONTROL_WBUF_ENABLE;
2056129198Scognet
2057129198Scognet	cpuctrl = parse_cpu_options(args, arm678_options, cpuctrl);
2058129198Scognet	cpuctrl = parse_cpu_options(args, arm7tdmi_options, cpuctrl);
2059129198Scognet
2060129198Scognet#ifdef __ARMEB__
2061129198Scognet	cpuctrl |= CPU_CONTROL_BEND_ENABLE;
2062129198Scognet#endif
2063129198Scognet
2064129198Scognet	/* Clear out the cache */
2065129198Scognet	cpu_idcache_wbinv_all();
2066129198Scognet
2067129198Scognet	/* Set the control register */
2068129198Scognet	ctrl = cpuctrl;
2069129198Scognet	cpu_control(0xffffffff, cpuctrl);
2070129198Scognet}
2071129198Scognet#endif	/* CPU_ARM7TDMI */
2072129198Scognet
2073129198Scognet#ifdef CPU_ARM8
2074129198Scognetstruct cpu_option arm8_options[] = {
2075129198Scognet	{ "arm8.cache",		BIC, OR,  CPU_CONTROL_IDC_ENABLE },
2076129198Scognet	{ "arm8.nocache",	OR,  BIC, CPU_CONTROL_IDC_ENABLE },
2077129198Scognet	{ "arm8.writebuf",	BIC, OR,  CPU_CONTROL_WBUF_ENABLE },
2078129198Scognet	{ "arm8.nowritebuf",	OR,  BIC, CPU_CONTROL_WBUF_ENABLE },
2079129198Scognet#ifdef COMPAT_12
2080129198Scognet	{ "branchpredict", 	BIC, OR,  CPU_CONTROL_BPRD_ENABLE },
2081129198Scognet#endif	/* COMPAT_12 */
2082129198Scognet	{ "cpu.branchpredict", 	BIC, OR,  CPU_CONTROL_BPRD_ENABLE },
2083129198Scognet	{ "arm8.branchpredict",	BIC, OR,  CPU_CONTROL_BPRD_ENABLE },
2084129198Scognet	{ NULL,			IGN, IGN, 0 }
2085129198Scognet};
2086129198Scognet
2087129198Scognetvoid
2088129198Scognetarm8_setup(args)
2089129198Scognet	char *args;
2090129198Scognet{
2091129198Scognet	int integer;
2092129198Scognet	int cpuctrl, cpuctrlmask;
2093129198Scognet	int clocktest;
2094129198Scognet	int setclock = 0;
2095129198Scognet
2096129198Scognet	cpuctrl = CPU_CONTROL_MMU_ENABLE | CPU_CONTROL_32BP_ENABLE
2097129198Scognet		 | CPU_CONTROL_32BD_ENABLE | CPU_CONTROL_SYST_ENABLE
2098129198Scognet		 | CPU_CONTROL_IDC_ENABLE | CPU_CONTROL_WBUF_ENABLE;
2099129198Scognet	cpuctrlmask = CPU_CONTROL_MMU_ENABLE | CPU_CONTROL_32BP_ENABLE
2100129198Scognet		 | CPU_CONTROL_32BD_ENABLE | CPU_CONTROL_SYST_ENABLE
2101129198Scognet		 | CPU_CONTROL_IDC_ENABLE | CPU_CONTROL_WBUF_ENABLE
2102129198Scognet		 | CPU_CONTROL_BPRD_ENABLE | CPU_CONTROL_ROM_ENABLE
2103129198Scognet		 | CPU_CONTROL_BEND_ENABLE | CPU_CONTROL_AFLT_ENABLE;
2104129198Scognet
2105129198Scognet#ifndef ARM32_DISABLE_ALIGNMENT_FAULTS
2106129198Scognet	cpuctrl |= CPU_CONTROL_AFLT_ENABLE;
2107129198Scognet#endif
2108129198Scognet
2109129198Scognet	cpuctrl = parse_cpu_options(args, arm678_options, cpuctrl);
2110129198Scognet	cpuctrl = parse_cpu_options(args, arm8_options, cpuctrl);
2111129198Scognet
2112129198Scognet#ifdef __ARMEB__
2113129198Scognet	cpuctrl |= CPU_CONTROL_BEND_ENABLE;
2114129198Scognet#endif
2115129198Scognet
2116129198Scognet	/* Get clock configuration */
2117129198Scognet	clocktest = arm8_clock_config(0, 0) & 0x0f;
2118129198Scognet
2119129198Scognet	/* Special ARM8 clock and test configuration */
2120129198Scognet	if (get_bootconf_option(args, "arm8.clock.reset", BOOTOPT_TYPE_BOOLEAN, &integer)) {
2121129198Scognet		clocktest = 0;
2122129198Scognet		setclock = 1;
2123129198Scognet	}
2124129198Scognet	if (get_bootconf_option(args, "arm8.clock.dynamic", BOOTOPT_TYPE_BOOLEAN, &integer)) {
2125129198Scognet		if (integer)
2126129198Scognet			clocktest |= 0x01;
2127129198Scognet		else
2128129198Scognet			clocktest &= ~(0x01);
2129129198Scognet		setclock = 1;
2130129198Scognet	}
2131129198Scognet	if (get_bootconf_option(args, "arm8.clock.sync", BOOTOPT_TYPE_BOOLEAN, &integer)) {
2132129198Scognet		if (integer)
2133129198Scognet			clocktest |= 0x02;
2134129198Scognet		else
2135129198Scognet			clocktest &= ~(0x02);
2136129198Scognet		setclock = 1;
2137129198Scognet	}
2138129198Scognet	if (get_bootconf_option(args, "arm8.clock.fast", BOOTOPT_TYPE_BININT, &integer)) {
2139129198Scognet		clocktest = (clocktest & ~0xc0) | (integer & 3) << 2;
2140129198Scognet		setclock = 1;
2141129198Scognet	}
2142129198Scognet	if (get_bootconf_option(args, "arm8.test", BOOTOPT_TYPE_BININT, &integer)) {
2143129198Scognet		clocktest |= (integer & 7) << 5;
2144129198Scognet		setclock = 1;
2145129198Scognet	}
2146129198Scognet
2147129198Scognet	/* Clear out the cache */
2148129198Scognet	cpu_idcache_wbinv_all();
2149129198Scognet
2150129198Scognet	/* Set the control register */
2151129198Scognet	ctrl = cpuctrl;
2152129198Scognet	cpu_control(0xffffffff, cpuctrl);
2153129198Scognet
2154236991Simp	/* Set the clock/test register */
2155129198Scognet	if (setclock)
2156129198Scognet		arm8_clock_config(0x7f, clocktest);
2157129198Scognet}
2158129198Scognet#endif	/* CPU_ARM8 */
2159129198Scognet
2160129198Scognet#ifdef CPU_ARM9
2161129198Scognetstruct cpu_option arm9_options[] = {
2162129198Scognet	{ "cpu.cache",		BIC, OR,  (CPU_CONTROL_IC_ENABLE | CPU_CONTROL_DC_ENABLE) },
2163129198Scognet	{ "cpu.nocache",	OR,  BIC, (CPU_CONTROL_IC_ENABLE | CPU_CONTROL_DC_ENABLE) },
2164129198Scognet	{ "arm9.cache",	BIC, OR,  (CPU_CONTROL_IC_ENABLE | CPU_CONTROL_DC_ENABLE) },
2165129198Scognet	{ "arm9.icache",	BIC, OR,  CPU_CONTROL_IC_ENABLE },
2166129198Scognet	{ "arm9.dcache",	BIC, OR,  CPU_CONTROL_DC_ENABLE },
2167129198Scognet	{ "cpu.writebuf",	BIC, OR,  CPU_CONTROL_WBUF_ENABLE },
2168129198Scognet	{ "cpu.nowritebuf",	OR,  BIC, CPU_CONTROL_WBUF_ENABLE },
2169129198Scognet	{ "arm9.writebuf",	BIC, OR,  CPU_CONTROL_WBUF_ENABLE },
2170129198Scognet	{ NULL,			IGN, IGN, 0 }
2171129198Scognet};
2172129198Scognet
2173129198Scognetvoid
2174129198Scognetarm9_setup(args)
2175129198Scognet	char *args;
2176129198Scognet{
2177129198Scognet	int cpuctrl, cpuctrlmask;
2178129198Scognet
2179129198Scognet	cpuctrl = CPU_CONTROL_MMU_ENABLE | CPU_CONTROL_32BP_ENABLE
2180129198Scognet	    | CPU_CONTROL_32BD_ENABLE | CPU_CONTROL_SYST_ENABLE
2181129198Scognet	    | CPU_CONTROL_IC_ENABLE | CPU_CONTROL_DC_ENABLE
2182157618Scognet	    | CPU_CONTROL_WBUF_ENABLE | CPU_CONTROL_LABT_ENABLE |
2183157618Scognet	    CPU_CONTROL_ROUNDROBIN;
2184129198Scognet	cpuctrlmask = CPU_CONTROL_MMU_ENABLE | CPU_CONTROL_32BP_ENABLE
2185129198Scognet		 | CPU_CONTROL_32BD_ENABLE | CPU_CONTROL_SYST_ENABLE
2186129198Scognet		 | CPU_CONTROL_IC_ENABLE | CPU_CONTROL_DC_ENABLE
2187129198Scognet		 | CPU_CONTROL_WBUF_ENABLE | CPU_CONTROL_ROM_ENABLE
2188129198Scognet		 | CPU_CONTROL_BEND_ENABLE | CPU_CONTROL_AFLT_ENABLE
2189146605Scognet		 | CPU_CONTROL_LABT_ENABLE | CPU_CONTROL_VECRELOC
2190146605Scognet		 | CPU_CONTROL_ROUNDROBIN;
2191129198Scognet
2192129198Scognet#ifndef ARM32_DISABLE_ALIGNMENT_FAULTS
2193129198Scognet	cpuctrl |= CPU_CONTROL_AFLT_ENABLE;
2194129198Scognet#endif
2195129198Scognet
2196129198Scognet	cpuctrl = parse_cpu_options(args, arm9_options, cpuctrl);
2197129198Scognet
2198129198Scognet#ifdef __ARMEB__
2199129198Scognet	cpuctrl |= CPU_CONTROL_BEND_ENABLE;
2200129198Scognet#endif
2201142050Scognet	if (vector_page == ARM_VECTORS_HIGH)
2202142050Scognet		cpuctrl |= CPU_CONTROL_VECRELOC;
2203129198Scognet
2204129198Scognet	/* Clear out the cache */
2205129198Scognet	cpu_idcache_wbinv_all();
2206129198Scognet
2207129198Scognet	/* Set the control register */
2208146605Scognet	cpu_control(cpuctrlmask, cpuctrl);
2209129198Scognet	ctrl = cpuctrl;
2210129198Scognet
2211129198Scognet}
2212129198Scognet#endif	/* CPU_ARM9 */
2213129198Scognet
2214172738Simp#if defined(CPU_ARM9E) || defined(CPU_ARM10)
2215129198Scognetstruct cpu_option arm10_options[] = {
2216129198Scognet	{ "cpu.cache",		BIC, OR,  (CPU_CONTROL_IC_ENABLE | CPU_CONTROL_DC_ENABLE) },
2217129198Scognet	{ "cpu.nocache",	OR,  BIC, (CPU_CONTROL_IC_ENABLE | CPU_CONTROL_DC_ENABLE) },
2218129198Scognet	{ "arm10.cache",	BIC, OR,  (CPU_CONTROL_IC_ENABLE | CPU_CONTROL_DC_ENABLE) },
2219129198Scognet	{ "arm10.icache",	BIC, OR,  CPU_CONTROL_IC_ENABLE },
2220129198Scognet	{ "arm10.dcache",	BIC, OR,  CPU_CONTROL_DC_ENABLE },
2221129198Scognet	{ "cpu.writebuf",	BIC, OR,  CPU_CONTROL_WBUF_ENABLE },
2222129198Scognet	{ "cpu.nowritebuf",	OR,  BIC, CPU_CONTROL_WBUF_ENABLE },
2223129198Scognet	{ "arm10.writebuf",	BIC, OR,  CPU_CONTROL_WBUF_ENABLE },
2224129198Scognet	{ NULL,			IGN, IGN, 0 }
2225129198Scognet};
2226129198Scognet
2227129198Scognetvoid
2228129198Scognetarm10_setup(args)
2229129198Scognet	char *args;
2230129198Scognet{
2231129198Scognet	int cpuctrl, cpuctrlmask;
2232129198Scognet
2233129198Scognet	cpuctrl = CPU_CONTROL_MMU_ENABLE | CPU_CONTROL_SYST_ENABLE
2234236991Simp	    | CPU_CONTROL_IC_ENABLE | CPU_CONTROL_DC_ENABLE
2235129198Scognet	    | CPU_CONTROL_WBUF_ENABLE | CPU_CONTROL_BPRD_ENABLE;
2236129198Scognet	cpuctrlmask = CPU_CONTROL_MMU_ENABLE | CPU_CONTROL_SYST_ENABLE
2237129198Scognet	    | CPU_CONTROL_IC_ENABLE | CPU_CONTROL_DC_ENABLE
2238129198Scognet	    | CPU_CONTROL_WBUF_ENABLE | CPU_CONTROL_ROM_ENABLE
2239129198Scognet	    | CPU_CONTROL_BEND_ENABLE | CPU_CONTROL_AFLT_ENABLE
2240129198Scognet	    | CPU_CONTROL_BPRD_ENABLE
2241129198Scognet	    | CPU_CONTROL_ROUNDROBIN | CPU_CONTROL_CPCLK;
2242129198Scognet
2243129198Scognet#ifndef ARM32_DISABLE_ALIGNMENT_FAULTS
2244129198Scognet	cpuctrl |= CPU_CONTROL_AFLT_ENABLE;
2245129198Scognet#endif
2246129198Scognet
2247129198Scognet	cpuctrl = parse_cpu_options(args, arm10_options, cpuctrl);
2248129198Scognet
2249129198Scognet#ifdef __ARMEB__
2250129198Scognet	cpuctrl |= CPU_CONTROL_BEND_ENABLE;
2251129198Scognet#endif
2252129198Scognet
2253129198Scognet	/* Clear out the cache */
2254129198Scognet	cpu_idcache_wbinv_all();
2255129198Scognet
2256129198Scognet	/* Now really make sure they are clean.  */
2257172738Simp	__asm __volatile ("mcr\tp15, 0, r0, c7, c7, 0" : : );
2258129198Scognet
2259174058Scognet	if (vector_page == ARM_VECTORS_HIGH)
2260174058Scognet		cpuctrl |= CPU_CONTROL_VECRELOC;
2261174058Scognet
2262129198Scognet	/* Set the control register */
2263129198Scognet	ctrl = cpuctrl;
2264129198Scognet	cpu_control(0xffffffff, cpuctrl);
2265129198Scognet
2266129198Scognet	/* And again. */
2267129198Scognet	cpu_idcache_wbinv_all();
2268129198Scognet}
2269172738Simp#endif	/* CPU_ARM9E || CPU_ARM10 */
2270129198Scognet
2271244480Sgonzo#if defined(CPU_ARM1136) || defined(CPU_ARM1176)
2272172738Simpstruct cpu_option arm11_options[] = {
2273172738Simp	{ "cpu.cache",		BIC, OR,  (CPU_CONTROL_IC_ENABLE | CPU_CONTROL_DC_ENABLE) },
2274172738Simp	{ "cpu.nocache",	OR,  BIC, (CPU_CONTROL_IC_ENABLE | CPU_CONTROL_DC_ENABLE) },
2275172738Simp	{ "arm11.cache",	BIC, OR,  (CPU_CONTROL_IC_ENABLE | CPU_CONTROL_DC_ENABLE) },
2276172738Simp	{ "arm11.icache",	BIC, OR,  CPU_CONTROL_IC_ENABLE },
2277172738Simp	{ "arm11.dcache",	BIC, OR,  CPU_CONTROL_DC_ENABLE },
2278172738Simp	{ NULL,			IGN, IGN, 0 }
2279172738Simp};
2280172738Simp
2281172738Simpvoid
2282244480Sgonzoarm11x6_setup(char *args)
2283172738Simp{
2284244480Sgonzo	int cpuctrl, cpuctrl_wax;
2285244480Sgonzo	uint32_t auxctrl, auxctrl_wax;
2286244480Sgonzo	uint32_t tmp, tmp2;
2287244480Sgonzo	uint32_t sbz=0;
2288244480Sgonzo	uint32_t cpuid;
2289172738Simp
2290244480Sgonzo	cpuid = cpufunc_id();
2291244480Sgonzo
2292244480Sgonzo	cpuctrl =
2293244480Sgonzo		CPU_CONTROL_MMU_ENABLE  |
2294244480Sgonzo		CPU_CONTROL_DC_ENABLE   |
2295244480Sgonzo		CPU_CONTROL_WBUF_ENABLE |
2296244480Sgonzo		CPU_CONTROL_32BP_ENABLE |
2297244480Sgonzo		CPU_CONTROL_32BD_ENABLE |
2298244480Sgonzo		CPU_CONTROL_LABT_ENABLE |
2299244480Sgonzo		CPU_CONTROL_SYST_ENABLE |
2300244480Sgonzo		CPU_CONTROL_IC_ENABLE;
2301244480Sgonzo
2302244480Sgonzo	/*
2303244480Sgonzo	 * "write as existing" bits
2304244480Sgonzo	 * inverse of this is mask
2305244480Sgonzo	 */
2306244480Sgonzo	cpuctrl_wax =
2307244480Sgonzo		(3 << 30) | /* SBZ */
2308244480Sgonzo		(1 << 29) | /* FA */
2309244480Sgonzo		(1 << 28) | /* TR */
2310244480Sgonzo		(3 << 26) | /* SBZ */
2311244480Sgonzo		(3 << 19) | /* SBZ */
2312244480Sgonzo		(1 << 17);  /* SBZ */
2313244480Sgonzo
2314244480Sgonzo	cpuctrl |= CPU_CONTROL_BPRD_ENABLE;
2315244480Sgonzo	cpuctrl |= CPU_CONTROL_V6_EXTPAGE;
2316244480Sgonzo
2317172738Simp	cpuctrl = parse_cpu_options(args, arm11_options, cpuctrl);
2318244480Sgonzo
2319172738Simp#ifdef __ARMEB__
2320172738Simp	cpuctrl |= CPU_CONTROL_BEND_ENABLE;
2321172738Simp#endif
2322244480Sgonzo
2323239701Sgonzo	if (vector_page == ARM_VECTORS_HIGH)
2324239701Sgonzo		cpuctrl |= CPU_CONTROL_VECRELOC;
2325172738Simp
2326244480Sgonzo	auxctrl = 0;
2327244480Sgonzo	auxctrl_wax = ~0;
2328244480Sgonzo	/*
2329244480Sgonzo	 * This options enables the workaround for the 364296 ARM1136
2330244480Sgonzo	 * r0pX errata (possible cache data corruption with
2331244480Sgonzo	 * hit-under-miss enabled). It sets the undocumented bit 31 in
2332244480Sgonzo	 * the auxiliary control register and the FI bit in the control
2333244480Sgonzo	 * register, thus disabling hit-under-miss without putting the
2334244480Sgonzo	 * processor into full low interrupt latency mode. ARM11MPCore
2335244480Sgonzo	 * is not affected.
2336244480Sgonzo	 */
2337244480Sgonzo	if ((cpuid & CPU_ID_CPU_MASK) == CPU_ID_ARM1136JS) { /* ARM1136JSr0pX */
2338244480Sgonzo		cpuctrl |= CPU_CONTROL_FI_ENABLE;
2339244480Sgonzo		auxctrl = ARM1136_AUXCTL_PFI;
2340244480Sgonzo		auxctrl_wax = ~ARM1136_AUXCTL_PFI;
2341244480Sgonzo	}
2342244480Sgonzo
2343244480Sgonzo	/*
2344244480Sgonzo	 * Enable an errata workaround
2345244480Sgonzo	 */
2346244480Sgonzo	if ((cpuid & CPU_ID_CPU_MASK) == CPU_ID_ARM1176JZS) { /* ARM1176JZSr0 */
2347244480Sgonzo		auxctrl = ARM1176_AUXCTL_PHD;
2348244480Sgonzo		auxctrl_wax = ~ARM1176_AUXCTL_PHD;
2349244480Sgonzo	}
2350244480Sgonzo
2351244480Sgonzo	/* Clear out the cache */
2352172738Simp	cpu_idcache_wbinv_all();
2353172738Simp
2354244480Sgonzo	/* Now really make sure they are clean.  */
2355244480Sgonzo	__asm volatile ("mcr\tp15, 0, %0, c7, c7, 0" : : "r"(sbz));
2356244480Sgonzo
2357244480Sgonzo	/* Allow detection code to find the VFP if it's fitted.  */
2358244480Sgonzo	__asm volatile ("mcr\tp15, 0, %0, c1, c0, 2" : : "r" (0x0fffffff));
2359244480Sgonzo
2360172738Simp	/* Set the control register */
2361239701Sgonzo	ctrl = cpuctrl;
2362244480Sgonzo	cpu_control(~cpuctrl_wax, cpuctrl);
2363172738Simp
2364244480Sgonzo	__asm volatile ("mrc	p15, 0, %0, c1, c0, 1\n\t"
2365244480Sgonzo			"and	%1, %0, %2\n\t"
2366244480Sgonzo			"orr	%1, %1, %3\n\t"
2367244480Sgonzo			"teq	%0, %1\n\t"
2368244480Sgonzo			"mcrne	p15, 0, %1, c1, c0, 1\n\t"
2369244480Sgonzo			: "=r"(tmp), "=r"(tmp2) :
2370244480Sgonzo			  "r"(auxctrl_wax), "r"(auxctrl));
2371244480Sgonzo
2372244480Sgonzo	/* And again. */
2373172738Simp	cpu_idcache_wbinv_all();
2374172738Simp}
2375244480Sgonzo#endif  /* CPU_ARM1136 || CPU_ARM1176 */
2376172738Simp
2377239268Sgonzo#ifdef CPU_MV_PJ4B
2378239268Sgonzovoid
2379239268Sgonzopj4bv7_setup(args)
2380239268Sgonzo	char *args;
2381239268Sgonzo{
2382239268Sgonzo	int cpuctrl;
2383239268Sgonzo
2384239268Sgonzo	pj4b_config();
2385239268Sgonzo
2386239268Sgonzo	cpuctrl = CPU_CONTROL_MMU_ENABLE;
2387239268Sgonzo#ifndef ARM32_DISABLE_ALIGNMENT_FAULTS
2388239268Sgonzo	cpuctrl |= CPU_CONTROL_AFLT_ENABLE;
2389239268Sgonzo#endif
2390239268Sgonzo	cpuctrl |= CPU_CONTROL_DC_ENABLE;
2391239268Sgonzo	cpuctrl |= (0xf << 3);
2392239268Sgonzo	cpuctrl |= CPU_CONTROL_BPRD_ENABLE;
2393239268Sgonzo	cpuctrl |= CPU_CONTROL_IC_ENABLE;
2394239268Sgonzo	if (vector_page == ARM_VECTORS_HIGH)
2395239268Sgonzo		cpuctrl |= CPU_CONTROL_VECRELOC;
2396239268Sgonzo	cpuctrl |= (0x5 << 16) | (1 < 22);
2397239268Sgonzo	cpuctrl |= CPU_CONTROL_V6_EXTPAGE;
2398239268Sgonzo
2399239268Sgonzo	/* Clear out the cache */
2400239268Sgonzo	cpu_idcache_wbinv_all();
2401239268Sgonzo
2402239268Sgonzo	/* Set the control register */
2403239268Sgonzo	ctrl = cpuctrl;
2404239268Sgonzo	cpu_control(0xFFFFFFFF, cpuctrl);
2405239268Sgonzo
2406239268Sgonzo	/* And again. */
2407239268Sgonzo	cpu_idcache_wbinv_all();
2408239268Sgonzo}
2409239268Sgonzo#endif /* CPU_MV_PJ4B */
2410239268Sgonzo
2411259640Sganbold#if defined(CPU_CORTEXA) || defined(CPU_KRAIT)
2412239268Sgonzo
2413239268Sgonzovoid
2414239268Sgonzocortexa_setup(char *args)
2415239268Sgonzo{
2416239268Sgonzo	int cpuctrl, cpuctrlmask;
2417239268Sgonzo
2418239268Sgonzo	cpuctrlmask = CPU_CONTROL_MMU_ENABLE |     /* MMU enable         [0] */
2419239268Sgonzo	    CPU_CONTROL_AFLT_ENABLE |    /* Alignment fault    [1] */
2420239268Sgonzo	    CPU_CONTROL_DC_ENABLE |      /* DCache enable      [2] */
2421239268Sgonzo	    CPU_CONTROL_BPRD_ENABLE |    /* Branch prediction [11] */
2422239268Sgonzo	    CPU_CONTROL_IC_ENABLE |      /* ICache enable     [12] */
2423239268Sgonzo	    CPU_CONTROL_VECRELOC;        /* Vector relocation [13] */
2424239268Sgonzo
2425239268Sgonzo	cpuctrl = CPU_CONTROL_MMU_ENABLE |
2426239268Sgonzo	    CPU_CONTROL_IC_ENABLE |
2427239268Sgonzo	    CPU_CONTROL_DC_ENABLE |
2428239268Sgonzo	    CPU_CONTROL_BPRD_ENABLE;
2429239268Sgonzo
2430239268Sgonzo#ifndef ARM32_DISABLE_ALIGNMENT_FAULTS
2431239268Sgonzo	cpuctrl |= CPU_CONTROL_AFLT_ENABLE;
2432239268Sgonzo#endif
2433239268Sgonzo
2434239268Sgonzo	/* Switch to big endian */
2435239268Sgonzo#ifdef __ARMEB__
2436239268Sgonzo	cpuctrl |= CPU_CONTROL_BEND_ENABLE;
2437239268Sgonzo#endif
2438239268Sgonzo
2439239268Sgonzo	/* Check if the vector page is at the high address (0xffff0000) */
2440239268Sgonzo	if (vector_page == ARM_VECTORS_HIGH)
2441239268Sgonzo		cpuctrl |= CPU_CONTROL_VECRELOC;
2442239268Sgonzo
2443239268Sgonzo	/* Clear out the cache */
2444239268Sgonzo	cpu_idcache_wbinv_all();
2445239268Sgonzo
2446239268Sgonzo	/* Set the control register */
2447239268Sgonzo	ctrl = cpuctrl;
2448239268Sgonzo	cpu_control(cpuctrlmask, cpuctrl);
2449239268Sgonzo
2450239268Sgonzo	/* And again. */
2451239268Sgonzo	cpu_idcache_wbinv_all();
2452239268Sgonzo#ifdef SMP
2453239268Sgonzo	armv7_auxctrl((1 << 6) | (1 << 0), (1 << 6) | (1 << 0)); /* Enable SMP + TLB broadcasting  */
2454239268Sgonzo#endif
2455239268Sgonzo}
2456239268Sgonzo#endif  /* CPU_CORTEXA */
2457239268Sgonzo
2458239268Sgonzo
2459129198Scognet#ifdef CPU_SA110
2460129198Scognetstruct cpu_option sa110_options[] = {
2461129198Scognet#ifdef COMPAT_12
2462129198Scognet	{ "nocache",		IGN, BIC, (CPU_CONTROL_IC_ENABLE | CPU_CONTROL_DC_ENABLE) },
2463129198Scognet	{ "nowritebuf",		IGN, BIC, CPU_CONTROL_WBUF_ENABLE },
2464129198Scognet#endif	/* COMPAT_12 */
2465129198Scognet	{ "cpu.cache",		BIC, OR,  (CPU_CONTROL_IC_ENABLE | CPU_CONTROL_DC_ENABLE) },
2466129198Scognet	{ "cpu.nocache",	OR,  BIC, (CPU_CONTROL_IC_ENABLE | CPU_CONTROL_DC_ENABLE) },
2467129198Scognet	{ "sa110.cache",	BIC, OR,  (CPU_CONTROL_IC_ENABLE | CPU_CONTROL_DC_ENABLE) },
2468129198Scognet	{ "sa110.icache",	BIC, OR,  CPU_CONTROL_IC_ENABLE },
2469129198Scognet	{ "sa110.dcache",	BIC, OR,  CPU_CONTROL_DC_ENABLE },
2470129198Scognet	{ "cpu.writebuf",	BIC, OR,  CPU_CONTROL_WBUF_ENABLE },
2471129198Scognet	{ "cpu.nowritebuf",	OR,  BIC, CPU_CONTROL_WBUF_ENABLE },
2472129198Scognet	{ "sa110.writebuf",	BIC, OR,  CPU_CONTROL_WBUF_ENABLE },
2473129198Scognet	{ NULL,			IGN, IGN, 0 }
2474129198Scognet};
2475129198Scognet
2476129198Scognetvoid
2477129198Scognetsa110_setup(args)
2478129198Scognet	char *args;
2479129198Scognet{
2480129198Scognet	int cpuctrl, cpuctrlmask;
2481129198Scognet
2482129198Scognet	cpuctrl = CPU_CONTROL_MMU_ENABLE | CPU_CONTROL_32BP_ENABLE
2483129198Scognet		 | CPU_CONTROL_32BD_ENABLE | CPU_CONTROL_SYST_ENABLE
2484129198Scognet		 | CPU_CONTROL_IC_ENABLE | CPU_CONTROL_DC_ENABLE
2485129198Scognet		 | CPU_CONTROL_WBUF_ENABLE;
2486129198Scognet	cpuctrlmask = CPU_CONTROL_MMU_ENABLE | CPU_CONTROL_32BP_ENABLE
2487129198Scognet		 | CPU_CONTROL_32BD_ENABLE | CPU_CONTROL_SYST_ENABLE
2488129198Scognet		 | CPU_CONTROL_IC_ENABLE | CPU_CONTROL_DC_ENABLE
2489129198Scognet		 | CPU_CONTROL_WBUF_ENABLE | CPU_CONTROL_ROM_ENABLE
2490129198Scognet		 | CPU_CONTROL_BEND_ENABLE | CPU_CONTROL_AFLT_ENABLE
2491129198Scognet		 | CPU_CONTROL_LABT_ENABLE | CPU_CONTROL_BPRD_ENABLE
2492129198Scognet		 | CPU_CONTROL_CPCLK;
2493129198Scognet
2494129198Scognet#ifndef ARM32_DISABLE_ALIGNMENT_FAULTS
2495129198Scognet	cpuctrl |= CPU_CONTROL_AFLT_ENABLE;
2496129198Scognet#endif
2497129198Scognet
2498129198Scognet	cpuctrl = parse_cpu_options(args, sa110_options, cpuctrl);
2499129198Scognet
2500129198Scognet#ifdef __ARMEB__
2501129198Scognet	cpuctrl |= CPU_CONTROL_BEND_ENABLE;
2502129198Scognet#endif
2503129198Scognet
2504129198Scognet	/* Clear out the cache */
2505129198Scognet	cpu_idcache_wbinv_all();
2506129198Scognet
2507129198Scognet	/* Set the control register */
2508129198Scognet	ctrl = cpuctrl;
2509129198Scognet/*	cpu_control(cpuctrlmask, cpuctrl);*/
2510129198Scognet	cpu_control(0xffffffff, cpuctrl);
2511129198Scognet
2512236991Simp	/*
2513129198Scognet	 * enable clockswitching, note that this doesn't read or write to r0,
2514129198Scognet	 * r0 is just to make it valid asm
2515129198Scognet	 */
2516129198Scognet	__asm ("mcr 15, 0, r0, c15, c1, 2");
2517129198Scognet}
2518129198Scognet#endif	/* CPU_SA110 */
2519129198Scognet
2520129198Scognet#if defined(CPU_SA1100) || defined(CPU_SA1110)
2521129198Scognetstruct cpu_option sa11x0_options[] = {
2522129198Scognet#ifdef COMPAT_12
2523129198Scognet	{ "nocache",		IGN, BIC, (CPU_CONTROL_IC_ENABLE | CPU_CONTROL_DC_ENABLE) },
2524129198Scognet	{ "nowritebuf",		IGN, BIC, CPU_CONTROL_WBUF_ENABLE },
2525129198Scognet#endif	/* COMPAT_12 */
2526129198Scognet	{ "cpu.cache",		BIC, OR,  (CPU_CONTROL_IC_ENABLE | CPU_CONTROL_DC_ENABLE) },
2527129198Scognet	{ "cpu.nocache",	OR,  BIC, (CPU_CONTROL_IC_ENABLE | CPU_CONTROL_DC_ENABLE) },
2528129198Scognet	{ "sa11x0.cache",	BIC, OR,  (CPU_CONTROL_IC_ENABLE | CPU_CONTROL_DC_ENABLE) },
2529129198Scognet	{ "sa11x0.icache",	BIC, OR,  CPU_CONTROL_IC_ENABLE },
2530129198Scognet	{ "sa11x0.dcache",	BIC, OR,  CPU_CONTROL_DC_ENABLE },
2531129198Scognet	{ "cpu.writebuf",	BIC, OR,  CPU_CONTROL_WBUF_ENABLE },
2532129198Scognet	{ "cpu.nowritebuf",	OR,  BIC, CPU_CONTROL_WBUF_ENABLE },
2533129198Scognet	{ "sa11x0.writebuf",	BIC, OR,  CPU_CONTROL_WBUF_ENABLE },
2534129198Scognet	{ NULL,			IGN, IGN, 0 }
2535129198Scognet};
2536129198Scognet
2537129198Scognetvoid
2538129198Scognetsa11x0_setup(args)
2539129198Scognet	char *args;
2540129198Scognet{
2541129198Scognet	int cpuctrl, cpuctrlmask;
2542129198Scognet
2543129198Scognet	cpuctrl = CPU_CONTROL_MMU_ENABLE | CPU_CONTROL_32BP_ENABLE
2544129198Scognet		 | CPU_CONTROL_32BD_ENABLE | CPU_CONTROL_SYST_ENABLE
2545129198Scognet		 | CPU_CONTROL_IC_ENABLE | CPU_CONTROL_DC_ENABLE
2546129198Scognet		 | CPU_CONTROL_WBUF_ENABLE | CPU_CONTROL_LABT_ENABLE;
2547129198Scognet	cpuctrlmask = CPU_CONTROL_MMU_ENABLE | CPU_CONTROL_32BP_ENABLE
2548129198Scognet		 | CPU_CONTROL_32BD_ENABLE | CPU_CONTROL_SYST_ENABLE
2549129198Scognet		 | CPU_CONTROL_IC_ENABLE | CPU_CONTROL_DC_ENABLE
2550129198Scognet		 | CPU_CONTROL_WBUF_ENABLE | CPU_CONTROL_ROM_ENABLE
2551129198Scognet		 | CPU_CONTROL_BEND_ENABLE | CPU_CONTROL_AFLT_ENABLE
2552129198Scognet		 | CPU_CONTROL_LABT_ENABLE | CPU_CONTROL_BPRD_ENABLE
2553129198Scognet		 | CPU_CONTROL_CPCLK | CPU_CONTROL_VECRELOC;
2554129198Scognet
2555129198Scognet#ifndef ARM32_DISABLE_ALIGNMENT_FAULTS
2556129198Scognet	cpuctrl |= CPU_CONTROL_AFLT_ENABLE;
2557129198Scognet#endif
2558129198Scognet
2559129198Scognet
2560129198Scognet	cpuctrl = parse_cpu_options(args, sa11x0_options, cpuctrl);
2561129198Scognet
2562129198Scognet#ifdef __ARMEB__
2563129198Scognet	cpuctrl |= CPU_CONTROL_BEND_ENABLE;
2564129198Scognet#endif
2565129198Scognet
2566129198Scognet	if (vector_page == ARM_VECTORS_HIGH)
2567129198Scognet		cpuctrl |= CPU_CONTROL_VECRELOC;
2568129198Scognet	/* Clear out the cache */
2569129198Scognet	cpu_idcache_wbinv_all();
2570236991Simp	/* Set the control register */
2571129198Scognet	ctrl = cpuctrl;
2572129198Scognet	cpu_control(0xffffffff, cpuctrl);
2573129198Scognet}
2574129198Scognet#endif	/* CPU_SA1100 || CPU_SA1110 */
2575129198Scognet
2576207611Skevlo#if defined(CPU_FA526) || defined(CPU_FA626TE)
2577201468Srpaulostruct cpu_option fa526_options[] = {
2578201468Srpaulo#ifdef COMPAT_12
2579201468Srpaulo	{ "nocache",		IGN, BIC, (CPU_CONTROL_IC_ENABLE |
2580201468Srpaulo					   CPU_CONTROL_DC_ENABLE) },
2581201468Srpaulo	{ "nowritebuf",		IGN, BIC, CPU_CONTROL_WBUF_ENABLE },
2582201468Srpaulo#endif	/* COMPAT_12 */
2583201468Srpaulo	{ "cpu.cache",		BIC, OR,  (CPU_CONTROL_IC_ENABLE |
2584201468Srpaulo					   CPU_CONTROL_DC_ENABLE) },
2585201468Srpaulo	{ "cpu.nocache",	OR,  BIC, (CPU_CONTROL_IC_ENABLE |
2586201468Srpaulo					   CPU_CONTROL_DC_ENABLE) },
2587201468Srpaulo	{ "cpu.writebuf",	BIC, OR,  CPU_CONTROL_WBUF_ENABLE },
2588201468Srpaulo	{ "cpu.nowritebuf",	OR,  BIC, CPU_CONTROL_WBUF_ENABLE },
2589201468Srpaulo	{ NULL,			IGN, IGN, 0 }
2590201468Srpaulo};
2591201468Srpaulo
2592201468Srpaulovoid
2593201468Srpaulofa526_setup(char *args)
2594201468Srpaulo{
2595201468Srpaulo	int cpuctrl, cpuctrlmask;
2596201468Srpaulo
2597201468Srpaulo	cpuctrl = CPU_CONTROL_MMU_ENABLE | CPU_CONTROL_32BP_ENABLE
2598201468Srpaulo		 | CPU_CONTROL_32BD_ENABLE | CPU_CONTROL_SYST_ENABLE
2599201468Srpaulo		 | CPU_CONTROL_IC_ENABLE | CPU_CONTROL_DC_ENABLE
2600204122Skevlo		 | CPU_CONTROL_WBUF_ENABLE | CPU_CONTROL_LABT_ENABLE
2601204122Skevlo		| CPU_CONTROL_BPRD_ENABLE;
2602201468Srpaulo	cpuctrlmask = CPU_CONTROL_MMU_ENABLE | CPU_CONTROL_32BP_ENABLE
2603201468Srpaulo		 | CPU_CONTROL_32BD_ENABLE | CPU_CONTROL_SYST_ENABLE
2604201468Srpaulo		 | CPU_CONTROL_IC_ENABLE | CPU_CONTROL_DC_ENABLE
2605201468Srpaulo		 | CPU_CONTROL_WBUF_ENABLE | CPU_CONTROL_ROM_ENABLE
2606201468Srpaulo		 | CPU_CONTROL_BEND_ENABLE | CPU_CONTROL_AFLT_ENABLE
2607201468Srpaulo		 | CPU_CONTROL_LABT_ENABLE | CPU_CONTROL_BPRD_ENABLE
2608201468Srpaulo		 | CPU_CONTROL_CPCLK | CPU_CONTROL_VECRELOC;
2609201468Srpaulo
2610201468Srpaulo#ifndef ARM32_DISABLE_ALIGNMENT_FAULTS
2611201468Srpaulo	cpuctrl |= CPU_CONTROL_AFLT_ENABLE;
2612201468Srpaulo#endif
2613201468Srpaulo
2614201468Srpaulo	cpuctrl = parse_cpu_options(args, fa526_options, cpuctrl);
2615201468Srpaulo
2616201468Srpaulo#ifdef __ARMEB__
2617201468Srpaulo	cpuctrl |= CPU_CONTROL_BEND_ENABLE;
2618201468Srpaulo#endif
2619201468Srpaulo
2620201468Srpaulo	if (vector_page == ARM_VECTORS_HIGH)
2621201468Srpaulo		cpuctrl |= CPU_CONTROL_VECRELOC;
2622201468Srpaulo
2623201468Srpaulo	/* Clear out the cache */
2624201468Srpaulo	cpu_idcache_wbinv_all();
2625201468Srpaulo
2626201468Srpaulo	/* Set the control register */
2627201468Srpaulo	ctrl = cpuctrl;
2628201468Srpaulo	cpu_control(0xffffffff, cpuctrl);
2629201468Srpaulo}
2630207611Skevlo#endif	/* CPU_FA526 || CPU_FA626TE */
2631201468Srpaulo
2632201468Srpaulo
2633129198Scognet#if defined(CPU_IXP12X0)
2634129198Scognetstruct cpu_option ixp12x0_options[] = {
2635129198Scognet	{ "cpu.cache",		BIC, OR,  (CPU_CONTROL_IC_ENABLE | CPU_CONTROL_DC_ENABLE) },
2636129198Scognet	{ "cpu.nocache",	OR,  BIC, (CPU_CONTROL_IC_ENABLE | CPU_CONTROL_DC_ENABLE) },
2637129198Scognet	{ "ixp12x0.cache",	BIC, OR,  (CPU_CONTROL_IC_ENABLE | CPU_CONTROL_DC_ENABLE) },
2638129198Scognet	{ "ixp12x0.icache",	BIC, OR,  CPU_CONTROL_IC_ENABLE },
2639129198Scognet	{ "ixp12x0.dcache",	BIC, OR,  CPU_CONTROL_DC_ENABLE },
2640129198Scognet	{ "cpu.writebuf",	BIC, OR,  CPU_CONTROL_WBUF_ENABLE },
2641129198Scognet	{ "cpu.nowritebuf",	OR,  BIC, CPU_CONTROL_WBUF_ENABLE },
2642129198Scognet	{ "ixp12x0.writebuf",	BIC, OR,  CPU_CONTROL_WBUF_ENABLE },
2643129198Scognet	{ NULL,			IGN, IGN, 0 }
2644129198Scognet};
2645129198Scognet
2646129198Scognetvoid
2647129198Scognetixp12x0_setup(args)
2648129198Scognet	char *args;
2649129198Scognet{
2650129198Scognet	int cpuctrl, cpuctrlmask;
2651129198Scognet
2652129198Scognet
2653129198Scognet	cpuctrl = CPU_CONTROL_MMU_ENABLE | CPU_CONTROL_DC_ENABLE
2654129198Scognet		 | CPU_CONTROL_WBUF_ENABLE | CPU_CONTROL_SYST_ENABLE
2655129198Scognet		 | CPU_CONTROL_IC_ENABLE;
2656129198Scognet
2657129198Scognet	cpuctrlmask = CPU_CONTROL_MMU_ENABLE | CPU_CONTROL_AFLT_ENABLE
2658129198Scognet		 | CPU_CONTROL_DC_ENABLE | CPU_CONTROL_WBUF_ENABLE
2659129198Scognet		 | CPU_CONTROL_BEND_ENABLE | CPU_CONTROL_SYST_ENABLE
2660129198Scognet		 | CPU_CONTROL_ROM_ENABLE | CPU_CONTROL_IC_ENABLE
2661129198Scognet		 | CPU_CONTROL_VECRELOC;
2662129198Scognet
2663129198Scognet#ifndef ARM32_DISABLE_ALIGNMENT_FAULTS
2664129198Scognet	cpuctrl |= CPU_CONTROL_AFLT_ENABLE;
2665129198Scognet#endif
2666129198Scognet
2667129198Scognet	cpuctrl = parse_cpu_options(args, ixp12x0_options, cpuctrl);
2668129198Scognet
2669129198Scognet#ifdef __ARMEB__
2670129198Scognet	cpuctrl |= CPU_CONTROL_BEND_ENABLE;
2671129198Scognet#endif
2672129198Scognet
2673129198Scognet	if (vector_page == ARM_VECTORS_HIGH)
2674129198Scognet		cpuctrl |= CPU_CONTROL_VECRELOC;
2675129198Scognet
2676129198Scognet	/* Clear out the cache */
2677129198Scognet	cpu_idcache_wbinv_all();
2678129198Scognet
2679236991Simp	/* Set the control register */
2680129198Scognet	ctrl = cpuctrl;
2681129198Scognet	/* cpu_control(0xffffffff, cpuctrl); */
2682129198Scognet	cpu_control(cpuctrlmask, cpuctrl);
2683129198Scognet}
2684129198Scognet#endif /* CPU_IXP12X0 */
2685129198Scognet
2686129198Scognet#if defined(CPU_XSCALE_80200) || defined(CPU_XSCALE_80321) || \
2687161592Scognet  defined(CPU_XSCALE_PXA2X0) || defined(CPU_XSCALE_IXP425) || \
2688164080Scognet  defined(CPU_XSCALE_80219) || defined(CPU_XSCALE_81342)
2689129198Scognetstruct cpu_option xscale_options[] = {
2690129198Scognet#ifdef COMPAT_12
2691129198Scognet	{ "branchpredict", 	BIC, OR,  CPU_CONTROL_BPRD_ENABLE },
2692129198Scognet	{ "nocache",		IGN, BIC, (CPU_CONTROL_IC_ENABLE | CPU_CONTROL_DC_ENABLE) },
2693129198Scognet#endif	/* COMPAT_12 */
2694129198Scognet	{ "cpu.branchpredict", 	BIC, OR,  CPU_CONTROL_BPRD_ENABLE },
2695129198Scognet	{ "cpu.cache",		BIC, OR,  (CPU_CONTROL_IC_ENABLE | CPU_CONTROL_DC_ENABLE) },
2696129198Scognet	{ "cpu.nocache",	OR,  BIC, (CPU_CONTROL_IC_ENABLE | CPU_CONTROL_DC_ENABLE) },
2697129198Scognet	{ "xscale.branchpredict", BIC, OR,  CPU_CONTROL_BPRD_ENABLE },
2698129198Scognet	{ "xscale.cache",	BIC, OR,  (CPU_CONTROL_IC_ENABLE | CPU_CONTROL_DC_ENABLE) },
2699129198Scognet	{ "xscale.icache",	BIC, OR,  CPU_CONTROL_IC_ENABLE },
2700129198Scognet	{ "xscale.dcache",	BIC, OR,  CPU_CONTROL_DC_ENABLE },
2701129198Scognet	{ NULL,			IGN, IGN, 0 }
2702129198Scognet};
2703129198Scognet
2704129198Scognetvoid
2705129198Scognetxscale_setup(args)
2706129198Scognet	char *args;
2707129198Scognet{
2708129198Scognet	uint32_t auxctl;
2709129198Scognet	int cpuctrl, cpuctrlmask;
2710129198Scognet
2711129198Scognet	/*
2712129198Scognet	 * The XScale Write Buffer is always enabled.  Our option
2713129198Scognet	 * is to enable/disable coalescing.  Note that bits 6:3
2714129198Scognet	 * must always be enabled.
2715129198Scognet	 */
2716129198Scognet
2717129198Scognet	cpuctrl = CPU_CONTROL_MMU_ENABLE | CPU_CONTROL_32BP_ENABLE
2718129198Scognet		 | CPU_CONTROL_32BD_ENABLE | CPU_CONTROL_SYST_ENABLE
2719129198Scognet		 | CPU_CONTROL_IC_ENABLE | CPU_CONTROL_DC_ENABLE
2720129198Scognet		 | CPU_CONTROL_WBUF_ENABLE | CPU_CONTROL_LABT_ENABLE
2721129198Scognet		 | CPU_CONTROL_BPRD_ENABLE;
2722129198Scognet	cpuctrlmask = CPU_CONTROL_MMU_ENABLE | CPU_CONTROL_32BP_ENABLE
2723129198Scognet		 | CPU_CONTROL_32BD_ENABLE | CPU_CONTROL_SYST_ENABLE
2724129198Scognet		 | CPU_CONTROL_IC_ENABLE | CPU_CONTROL_DC_ENABLE
2725129198Scognet		 | CPU_CONTROL_WBUF_ENABLE | CPU_CONTROL_ROM_ENABLE
2726129198Scognet		 | CPU_CONTROL_BEND_ENABLE | CPU_CONTROL_AFLT_ENABLE
2727129198Scognet		 | CPU_CONTROL_LABT_ENABLE | CPU_CONTROL_BPRD_ENABLE
2728171618Scognet		 | CPU_CONTROL_CPCLK | CPU_CONTROL_VECRELOC | \
2729171618Scognet		 CPU_CONTROL_L2_ENABLE;
2730129198Scognet
2731129198Scognet#ifndef ARM32_DISABLE_ALIGNMENT_FAULTS
2732129198Scognet	cpuctrl |= CPU_CONTROL_AFLT_ENABLE;
2733129198Scognet#endif
2734129198Scognet
2735129198Scognet	cpuctrl = parse_cpu_options(args, xscale_options, cpuctrl);
2736129198Scognet
2737129198Scognet#ifdef __ARMEB__
2738129198Scognet	cpuctrl |= CPU_CONTROL_BEND_ENABLE;
2739129198Scognet#endif
2740129198Scognet
2741129198Scognet	if (vector_page == ARM_VECTORS_HIGH)
2742129198Scognet		cpuctrl |= CPU_CONTROL_VECRELOC;
2743171618Scognet#ifdef CPU_XSCALE_CORE3
2744171618Scognet	cpuctrl |= CPU_CONTROL_L2_ENABLE;
2745171618Scognet#endif
2746129198Scognet
2747129198Scognet	/* Clear out the cache */
2748129198Scognet	cpu_idcache_wbinv_all();
2749129198Scognet
2750129198Scognet	/*
2751129198Scognet	 * Set the control register.  Note that bits 6:3 must always
2752129198Scognet	 * be set to 1.
2753129198Scognet	 */
2754129198Scognet	ctrl = cpuctrl;
2755129198Scognet/*	cpu_control(cpuctrlmask, cpuctrl);*/
2756129198Scognet	cpu_control(0xffffffff, cpuctrl);
2757129198Scognet
2758129198Scognet	/* Make sure write coalescing is turned on */
2759129198Scognet	__asm __volatile("mrc p15, 0, %0, c1, c0, 1"
2760129198Scognet		: "=r" (auxctl));
2761129198Scognet#ifdef XSCALE_NO_COALESCE_WRITES
2762129198Scognet	auxctl |= XSCALE_AUXCTL_K;
2763129198Scognet#else
2764129198Scognet	auxctl &= ~XSCALE_AUXCTL_K;
2765129198Scognet#endif
2766171618Scognet#ifdef CPU_XSCALE_CORE3
2767171618Scognet	auxctl |= XSCALE_AUXCTL_LLR;
2768171618Scognet	auxctl |= XSCALE_AUXCTL_MD_MASK;
2769171618Scognet#endif
2770129198Scognet	__asm __volatile("mcr p15, 0, %0, c1, c0, 1"
2771129198Scognet		: : "r" (auxctl));
2772129198Scognet}
2773236991Simp#endif	/* CPU_XSCALE_80200 || CPU_XSCALE_80321 || CPU_XSCALE_PXA2X0 || CPU_XSCALE_IXP425
2774161592Scognet	   CPU_XSCALE_80219 */
2775