1129198Scognet/*	$NetBSD: cpufunc.c,v 1.65 2003/11/05 12:53:15 scw Exp $	*/
2129198Scognet
3139735Simp/*-
4129198Scognet * arm9 support code Copyright (C) 2001 ARM Ltd
5129198Scognet * Copyright (c) 1997 Mark Brinicombe.
6129198Scognet * Copyright (c) 1997 Causality Limited
7129198Scognet * All rights reserved.
8129198Scognet *
9129198Scognet * Redistribution and use in source and binary forms, with or without
10129198Scognet * modification, are permitted provided that the following conditions
11129198Scognet * are met:
12129198Scognet * 1. Redistributions of source code must retain the above copyright
13129198Scognet *    notice, this list of conditions and the following disclaimer.
14129198Scognet * 2. Redistributions in binary form must reproduce the above copyright
15129198Scognet *    notice, this list of conditions and the following disclaimer in the
16129198Scognet *    documentation and/or other materials provided with the distribution.
17129198Scognet * 3. All advertising materials mentioning features or use of this software
18129198Scognet *    must display the following acknowledgement:
19129198Scognet *	This product includes software developed by Causality Limited.
20129198Scognet * 4. The name of Causality Limited may not be used to endorse or promote
21129198Scognet *    products derived from this software without specific prior written
22129198Scognet *    permission.
23129198Scognet *
24129198Scognet * THIS SOFTWARE IS PROVIDED BY CAUSALITY LIMITED ``AS IS'' AND ANY EXPRESS
25129198Scognet * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
26129198Scognet * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
27129198Scognet * DISCLAIMED. IN NO EVENT SHALL CAUSALITY LIMITED BE LIABLE FOR ANY DIRECT,
28129198Scognet * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
29129198Scognet * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
30129198Scognet * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
31129198Scognet * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
32129198Scognet * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
33129198Scognet * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
34129198Scognet * SUCH DAMAGE.
35129198Scognet *
36129198Scognet * RiscBSD kernel project
37129198Scognet *
38129198Scognet * cpufuncs.c
39129198Scognet *
40129198Scognet * C functions for supporting CPU / MMU / TLB specific operations.
41129198Scognet *
42129198Scognet * Created      : 30/01/97
43129198Scognet */
44129198Scognet#include <sys/cdefs.h>
45129198Scognet__FBSDID("$FreeBSD$");
46129198Scognet
47129198Scognet#include <sys/param.h>
48129198Scognet#include <sys/systm.h>
49129198Scognet#include <sys/lock.h>
50129198Scognet#include <sys/mutex.h>
51132472Scognet#include <sys/bus.h>
52132472Scognet#include <machine/bus.h>
53129198Scognet#include <machine/cpu.h>
54129198Scognet#include <machine/disassem.h>
55129198Scognet
56129198Scognet#include <vm/vm.h>
57129198Scognet#include <vm/pmap.h>
58166655Scognet#include <vm/uma.h>
59129198Scognet
60129198Scognet#include <machine/cpuconf.h>
61129198Scognet#include <machine/cpufunc.h>
62129198Scognet#include <machine/bootconfig.h>
63129198Scognet
64129198Scognet#ifdef CPU_XSCALE_80200
65135646Scognet#include <arm/xscale/i80200/i80200reg.h>
66135646Scognet#include <arm/xscale/i80200/i80200var.h>
67129198Scognet#endif
68129198Scognet
69161592Scognet#if defined(CPU_XSCALE_80321) || defined(CPU_XSCALE_80219)
70135646Scognet#include <arm/xscale/i80321/i80321reg.h>
71135646Scognet#include <arm/xscale/i80321/i80321var.h>
72129198Scognet#endif
73129198Scognet
74243579Smarcel/*
75243579Smarcel * Some definitions in i81342reg.h clash with i80321reg.h.
76243579Smarcel * This only happens for the LINT kernel. As it happens,
77243579Smarcel * we don't need anything from i81342reg.h that we already
78243579Smarcel * got from somewhere else during a LINT compile.
79243579Smarcel */
80243579Smarcel#if defined(CPU_XSCALE_81342) && !defined(COMPILING_LINT)
81164080Scognet#include <arm/xscale/i8134x/i81342reg.h>
82164080Scognet#endif
83164080Scognet
84129198Scognet#ifdef CPU_XSCALE_IXP425
85135646Scognet#include <arm/xscale/ixp425/ixp425reg.h>
86135646Scognet#include <arm/xscale/ixp425/ixp425var.h>
87129198Scognet#endif
88129198Scognet
89129198Scognet/* PRIMARY CACHE VARIABLES */
90129198Scognetint	arm_picache_size;
91129198Scognetint	arm_picache_line_size;
92129198Scognetint	arm_picache_ways;
93129198Scognet
94129198Scognetint	arm_pdcache_size;	/* and unified */
95129198Scognetint	arm_pdcache_line_size;
96129198Scognetint	arm_pdcache_ways;
97129198Scognet
98129198Scognetint	arm_pcache_type;
99129198Scognetint	arm_pcache_unified;
100129198Scognet
101129198Scognetint	arm_dcache_align;
102129198Scognetint	arm_dcache_align_mask;
103129198Scognet
104239268Sgonzou_int	arm_cache_level;
105239268Sgonzou_int	arm_cache_type[14];
106239268Sgonzou_int	arm_cache_loc;
107239268Sgonzo
108129198Scognet/* 1 == use cpu_sleep(), 0 == don't */
109129198Scognetint cpu_do_powersave;
110129198Scognetint ctrl;
111129198Scognet
112129198Scognet#ifdef CPU_ARM9
113129198Scognetstruct cpu_functions arm9_cpufuncs = {
114129198Scognet	/* CPU functions */
115129198Scognet
116129198Scognet	cpufunc_id,			/* id			*/
117129198Scognet	cpufunc_nullop,			/* cpwait		*/
118129198Scognet
119129198Scognet	/* MMU functions */
120129198Scognet
121129198Scognet	cpufunc_control,		/* control		*/
122129198Scognet	cpufunc_domains,		/* Domain		*/
123129198Scognet	arm9_setttb,			/* Setttb		*/
124129198Scognet	cpufunc_faultstatus,		/* Faultstatus		*/
125129198Scognet	cpufunc_faultaddress,		/* Faultaddress		*/
126129198Scognet
127129198Scognet	/* TLB functions */
128129198Scognet
129129198Scognet	armv4_tlb_flushID,		/* tlb_flushID		*/
130129198Scognet	arm9_tlb_flushID_SE,		/* tlb_flushID_SE	*/
131129198Scognet	armv4_tlb_flushI,		/* tlb_flushI		*/
132129198Scognet	(void *)armv4_tlb_flushI,	/* tlb_flushI_SE	*/
133129198Scognet	armv4_tlb_flushD,		/* tlb_flushD		*/
134129198Scognet	armv4_tlb_flushD_SE,		/* tlb_flushD_SE	*/
135129198Scognet
136129198Scognet	/* Cache operations */
137129198Scognet
138146605Scognet	arm9_icache_sync_all,		/* icache_sync_all	*/
139146605Scognet	arm9_icache_sync_range,		/* icache_sync_range	*/
140129198Scognet
141146605Scognet	arm9_dcache_wbinv_all,		/* dcache_wbinv_all	*/
142146605Scognet	arm9_dcache_wbinv_range,	/* dcache_wbinv_range	*/
143195798Sraj	arm9_dcache_inv_range,		/* dcache_inv_range	*/
144146605Scognet	arm9_dcache_wb_range,		/* dcache_wb_range	*/
145129198Scognet
146266203Sian	armv4_idcache_inv_all,		/* idcache_inv_all	*/
147146605Scognet	arm9_idcache_wbinv_all,		/* idcache_wbinv_all	*/
148146605Scognet	arm9_idcache_wbinv_range,	/* idcache_wbinv_range	*/
149171618Scognet	cpufunc_nullop,			/* l2cache_wbinv_all	*/
150171781Scognet	(void *)cpufunc_nullop,		/* l2cache_wbinv_range	*/
151171781Scognet	(void *)cpufunc_nullop,		/* l2cache_inv_range	*/
152171781Scognet	(void *)cpufunc_nullop,		/* l2cache_wb_range	*/
153266387Sian	(void *)cpufunc_nullop,         /* l2cache_drain_writebuf */
154129198Scognet
155129198Scognet	/* Other functions */
156129198Scognet
157129198Scognet	cpufunc_nullop,			/* flush_prefetchbuf	*/
158129198Scognet	armv4_drain_writebuf,		/* drain_writebuf	*/
159129198Scognet	cpufunc_nullop,			/* flush_brnchtgt_C	*/
160129198Scognet	(void *)cpufunc_nullop,		/* flush_brnchtgt_E	*/
161129198Scognet
162129198Scognet	(void *)cpufunc_nullop,		/* sleep		*/
163129198Scognet
164129198Scognet	/* Soft functions */
165129198Scognet
166129198Scognet	cpufunc_null_fixup,		/* dataabt_fixup	*/
167129198Scognet	cpufunc_null_fixup,		/* prefetchabt_fixup	*/
168129198Scognet
169129198Scognet	arm9_context_switch,		/* context_switch	*/
170129198Scognet
171129198Scognet	arm9_setup			/* cpu setup		*/
172129198Scognet
173129198Scognet};
174129198Scognet#endif /* CPU_ARM9 */
175129198Scognet
176172738Simp#if defined(CPU_ARM9E) || defined(CPU_ARM10)
177172738Simpstruct cpu_functions armv5_ec_cpufuncs = {
178172738Simp	/* CPU functions */
179172738Simp
180172738Simp	cpufunc_id,			/* id			*/
181172738Simp	cpufunc_nullop,			/* cpwait		*/
182172738Simp
183172738Simp	/* MMU functions */
184172738Simp
185172738Simp	cpufunc_control,		/* control		*/
186172738Simp	cpufunc_domains,		/* Domain		*/
187172738Simp	armv5_ec_setttb,		/* Setttb		*/
188172738Simp	cpufunc_faultstatus,		/* Faultstatus		*/
189172738Simp	cpufunc_faultaddress,		/* Faultaddress		*/
190172738Simp
191172738Simp	/* TLB functions */
192172738Simp
193172738Simp	armv4_tlb_flushID,		/* tlb_flushID		*/
194172738Simp	arm10_tlb_flushID_SE,		/* tlb_flushID_SE	*/
195172738Simp	armv4_tlb_flushI,		/* tlb_flushI		*/
196172738Simp	arm10_tlb_flushI_SE,		/* tlb_flushI_SE	*/
197172738Simp	armv4_tlb_flushD,		/* tlb_flushD		*/
198172738Simp	armv4_tlb_flushD_SE,		/* tlb_flushD_SE	*/
199172738Simp
200172738Simp	/* Cache operations */
201172738Simp
202172738Simp	armv5_ec_icache_sync_all,	/* icache_sync_all	*/
203172738Simp	armv5_ec_icache_sync_range,	/* icache_sync_range	*/
204172738Simp
205172738Simp	armv5_ec_dcache_wbinv_all,	/* dcache_wbinv_all	*/
206172738Simp	armv5_ec_dcache_wbinv_range,	/* dcache_wbinv_range	*/
207195798Sraj	armv5_ec_dcache_inv_range,	/* dcache_inv_range	*/
208172738Simp	armv5_ec_dcache_wb_range,	/* dcache_wb_range	*/
209172738Simp
210266203Sian	armv4_idcache_inv_all,		/* idcache_inv_all	*/
211172738Simp	armv5_ec_idcache_wbinv_all,	/* idcache_wbinv_all	*/
212172738Simp	armv5_ec_idcache_wbinv_range,	/* idcache_wbinv_range	*/
213172738Simp
214173442Scognet	cpufunc_nullop,                 /* l2cache_wbinv_all    */
215173442Scognet	(void *)cpufunc_nullop,         /* l2cache_wbinv_range  */
216173442Scognet      	(void *)cpufunc_nullop,         /* l2cache_inv_range    */
217173442Scognet	(void *)cpufunc_nullop,         /* l2cache_wb_range     */
218266387Sian	(void *)cpufunc_nullop,         /* l2cache_drain_writebuf */
219236991Simp
220172738Simp	/* Other functions */
221172738Simp
222172738Simp	cpufunc_nullop,			/* flush_prefetchbuf	*/
223172738Simp	armv4_drain_writebuf,		/* drain_writebuf	*/
224172738Simp	cpufunc_nullop,			/* flush_brnchtgt_C	*/
225172738Simp	(void *)cpufunc_nullop,		/* flush_brnchtgt_E	*/
226172738Simp
227172738Simp	(void *)cpufunc_nullop,		/* sleep		*/
228172738Simp
229172738Simp	/* Soft functions */
230172738Simp
231172738Simp	cpufunc_null_fixup,		/* dataabt_fixup	*/
232172738Simp	cpufunc_null_fixup,		/* prefetchabt_fixup	*/
233172738Simp
234172738Simp	arm10_context_switch,		/* context_switch	*/
235172738Simp
236172738Simp	arm10_setup			/* cpu setup		*/
237172738Simp
238172738Simp};
239183835Sraj
240186933Srajstruct cpu_functions sheeva_cpufuncs = {
241183835Sraj	/* CPU functions */
242183835Sraj
243183835Sraj	cpufunc_id,			/* id			*/
244183835Sraj	cpufunc_nullop,			/* cpwait		*/
245183835Sraj
246183835Sraj	/* MMU functions */
247183835Sraj
248183835Sraj	cpufunc_control,		/* control		*/
249183835Sraj	cpufunc_domains,		/* Domain		*/
250186933Sraj	sheeva_setttb,			/* Setttb		*/
251183835Sraj	cpufunc_faultstatus,		/* Faultstatus		*/
252183835Sraj	cpufunc_faultaddress,		/* Faultaddress		*/
253183835Sraj
254183835Sraj	/* TLB functions */
255183835Sraj
256183835Sraj	armv4_tlb_flushID,		/* tlb_flushID		*/
257183835Sraj	arm10_tlb_flushID_SE,		/* tlb_flushID_SE	*/
258183835Sraj	armv4_tlb_flushI,		/* tlb_flushI		*/
259183835Sraj	arm10_tlb_flushI_SE,		/* tlb_flushI_SE	*/
260183835Sraj	armv4_tlb_flushD,		/* tlb_flushD		*/
261183835Sraj	armv4_tlb_flushD_SE,		/* tlb_flushD_SE	*/
262183835Sraj
263183835Sraj	/* Cache operations */
264183835Sraj
265183835Sraj	armv5_ec_icache_sync_all,	/* icache_sync_all	*/
266183835Sraj	armv5_ec_icache_sync_range,	/* icache_sync_range	*/
267183835Sraj
268183835Sraj	armv5_ec_dcache_wbinv_all,	/* dcache_wbinv_all	*/
269186933Sraj	sheeva_dcache_wbinv_range,	/* dcache_wbinv_range	*/
270186933Sraj	sheeva_dcache_inv_range,	/* dcache_inv_range	*/
271186933Sraj	sheeva_dcache_wb_range,		/* dcache_wb_range	*/
272183835Sraj
273266203Sian	armv4_idcache_inv_all,		/* idcache_inv_all	*/
274183835Sraj	armv5_ec_idcache_wbinv_all,	/* idcache_wbinv_all	*/
275186933Sraj	sheeva_idcache_wbinv_range,	/* idcache_wbinv_all	*/
276183835Sraj
277186933Sraj	sheeva_l2cache_wbinv_all,	/* l2cache_wbinv_all    */
278186933Sraj	sheeva_l2cache_wbinv_range,	/* l2cache_wbinv_range  */
279186933Sraj	sheeva_l2cache_inv_range,	/* l2cache_inv_range    */
280186933Sraj	sheeva_l2cache_wb_range,	/* l2cache_wb_range     */
281266387Sian	(void *)cpufunc_nullop,         /* l2cache_drain_writebuf */
282183835Sraj
283183835Sraj	/* Other functions */
284183835Sraj
285183835Sraj	cpufunc_nullop,			/* flush_prefetchbuf	*/
286183835Sraj	armv4_drain_writebuf,		/* drain_writebuf	*/
287183835Sraj	cpufunc_nullop,			/* flush_brnchtgt_C	*/
288183835Sraj	(void *)cpufunc_nullop,		/* flush_brnchtgt_E	*/
289183835Sraj
290212825Smav	sheeva_cpu_sleep,		/* sleep		*/
291183835Sraj
292183835Sraj	/* Soft functions */
293183835Sraj
294183835Sraj	cpufunc_null_fixup,		/* dataabt_fixup	*/
295183835Sraj	cpufunc_null_fixup,		/* prefetchabt_fixup	*/
296183835Sraj
297183835Sraj	arm10_context_switch,		/* context_switch	*/
298183835Sraj
299183835Sraj	arm10_setup			/* cpu setup		*/
300183835Sraj};
301172738Simp#endif /* CPU_ARM9E || CPU_ARM10 */
302172738Simp
303129198Scognet#ifdef CPU_ARM10
304129198Scognetstruct cpu_functions arm10_cpufuncs = {
305129198Scognet	/* CPU functions */
306129198Scognet
307129198Scognet	cpufunc_id,			/* id			*/
308129198Scognet	cpufunc_nullop,			/* cpwait		*/
309129198Scognet
310129198Scognet	/* MMU functions */
311129198Scognet
312129198Scognet	cpufunc_control,		/* control		*/
313129198Scognet	cpufunc_domains,		/* Domain		*/
314129198Scognet	arm10_setttb,			/* Setttb		*/
315129198Scognet	cpufunc_faultstatus,		/* Faultstatus		*/
316129198Scognet	cpufunc_faultaddress,		/* Faultaddress		*/
317129198Scognet
318129198Scognet	/* TLB functions */
319129198Scognet
320129198Scognet	armv4_tlb_flushID,		/* tlb_flushID		*/
321129198Scognet	arm10_tlb_flushID_SE,		/* tlb_flushID_SE	*/
322129198Scognet	armv4_tlb_flushI,		/* tlb_flushI		*/
323129198Scognet	arm10_tlb_flushI_SE,		/* tlb_flushI_SE	*/
324129198Scognet	armv4_tlb_flushD,		/* tlb_flushD		*/
325129198Scognet	armv4_tlb_flushD_SE,		/* tlb_flushD_SE	*/
326129198Scognet
327129198Scognet	/* Cache operations */
328129198Scognet
329129198Scognet	arm10_icache_sync_all,		/* icache_sync_all	*/
330129198Scognet	arm10_icache_sync_range,	/* icache_sync_range	*/
331129198Scognet
332129198Scognet	arm10_dcache_wbinv_all,		/* dcache_wbinv_all	*/
333129198Scognet	arm10_dcache_wbinv_range,	/* dcache_wbinv_range	*/
334129198Scognet	arm10_dcache_inv_range,		/* dcache_inv_range	*/
335129198Scognet	arm10_dcache_wb_range,		/* dcache_wb_range	*/
336129198Scognet
337266203Sian	armv4_idcache_inv_all,		/* idcache_inv_all	*/
338129198Scognet	arm10_idcache_wbinv_all,	/* idcache_wbinv_all	*/
339129198Scognet	arm10_idcache_wbinv_range,	/* idcache_wbinv_range	*/
340171618Scognet	cpufunc_nullop,			/* l2cache_wbinv_all	*/
341171781Scognet	(void *)cpufunc_nullop,		/* l2cache_wbinv_range	*/
342171781Scognet	(void *)cpufunc_nullop,		/* l2cache_inv_range	*/
343171781Scognet	(void *)cpufunc_nullop,		/* l2cache_wb_range	*/
344266387Sian	(void *)cpufunc_nullop,         /* l2cache_drain_writebuf */
345129198Scognet
346129198Scognet	/* Other functions */
347129198Scognet
348129198Scognet	cpufunc_nullop,			/* flush_prefetchbuf	*/
349129198Scognet	armv4_drain_writebuf,		/* drain_writebuf	*/
350129198Scognet	cpufunc_nullop,			/* flush_brnchtgt_C	*/
351129198Scognet	(void *)cpufunc_nullop,		/* flush_brnchtgt_E	*/
352129198Scognet
353129198Scognet	(void *)cpufunc_nullop,		/* sleep		*/
354129198Scognet
355129198Scognet	/* Soft functions */
356129198Scognet
357129198Scognet	cpufunc_null_fixup,		/* dataabt_fixup	*/
358129198Scognet	cpufunc_null_fixup,		/* prefetchabt_fixup	*/
359129198Scognet
360129198Scognet	arm10_context_switch,		/* context_switch	*/
361129198Scognet
362129198Scognet	arm10_setup			/* cpu setup		*/
363129198Scognet
364129198Scognet};
365129198Scognet#endif /* CPU_ARM10 */
366129198Scognet
367239268Sgonzo#ifdef CPU_MV_PJ4B
368239268Sgonzostruct cpu_functions pj4bv7_cpufuncs = {
369239268Sgonzo	/* CPU functions */
370239268Sgonzo
371239268Sgonzo	cpufunc_id,			/* id			*/
372239268Sgonzo	arm11_drain_writebuf,		/* cpwait		*/
373239268Sgonzo
374239268Sgonzo	/* MMU functions */
375239268Sgonzo
376239268Sgonzo	cpufunc_control,		/* control		*/
377239268Sgonzo	cpufunc_domains,		/* Domain		*/
378239268Sgonzo	pj4b_setttb,			/* Setttb		*/
379239268Sgonzo	cpufunc_faultstatus,		/* Faultstatus		*/
380239268Sgonzo	cpufunc_faultaddress,		/* Faultaddress		*/
381239268Sgonzo
382239268Sgonzo	/* TLB functions */
383239268Sgonzo
384239268Sgonzo	armv7_tlb_flushID,		/* tlb_flushID		*/
385239268Sgonzo	armv7_tlb_flushID_SE,		/* tlb_flushID_SE	*/
386239268Sgonzo	armv7_tlb_flushID,		/* tlb_flushI		*/
387239268Sgonzo	armv7_tlb_flushID_SE,		/* tlb_flushI_SE	*/
388239268Sgonzo	armv7_tlb_flushID,		/* tlb_flushD		*/
389239268Sgonzo	armv7_tlb_flushID_SE,		/* tlb_flushD_SE	*/
390239268Sgonzo
391239268Sgonzo	/* Cache operations */
392239268Sgonzo	armv7_idcache_wbinv_all,	/* icache_sync_all	*/
393239268Sgonzo	armv7_icache_sync_range,	/* icache_sync_range	*/
394239268Sgonzo
395239268Sgonzo	armv7_dcache_wbinv_all,		/* dcache_wbinv_all	*/
396239268Sgonzo	armv7_dcache_wbinv_range,	/* dcache_wbinv_range	*/
397239268Sgonzo	armv7_dcache_inv_range,		/* dcache_inv_range	*/
398239268Sgonzo	armv7_dcache_wb_range,		/* dcache_wb_range	*/
399239268Sgonzo
400266203Sian	armv7_idcache_inv_all,		/* idcache_inv_all	*/
401239268Sgonzo	armv7_idcache_wbinv_all,	/* idcache_wbinv_all	*/
402239268Sgonzo	armv7_idcache_wbinv_range,	/* idcache_wbinv_all	*/
403239268Sgonzo
404239268Sgonzo	(void *)cpufunc_nullop,		/* l2cache_wbinv_all	*/
405239268Sgonzo	(void *)cpufunc_nullop,		/* l2cache_wbinv_range	*/
406239268Sgonzo	(void *)cpufunc_nullop,		/* l2cache_inv_range	*/
407239268Sgonzo	(void *)cpufunc_nullop,		/* l2cache_wb_range	*/
408266387Sian	(void *)cpufunc_nullop,         /* l2cache_drain_writebuf */
409239268Sgonzo
410239268Sgonzo	/* Other functions */
411239268Sgonzo
412239268Sgonzo	pj4b_drain_readbuf,		/* flush_prefetchbuf	*/
413239268Sgonzo	arm11_drain_writebuf,		/* drain_writebuf	*/
414239268Sgonzo	pj4b_flush_brnchtgt_all,	/* flush_brnchtgt_C	*/
415239268Sgonzo	pj4b_flush_brnchtgt_va,		/* flush_brnchtgt_E	*/
416239268Sgonzo
417239268Sgonzo	(void *)cpufunc_nullop,		/* sleep		*/
418239268Sgonzo
419239268Sgonzo	/* Soft functions */
420239268Sgonzo
421239268Sgonzo	cpufunc_null_fixup,		/* dataabt_fixup	*/
422239268Sgonzo	cpufunc_null_fixup,		/* prefetchabt_fixup	*/
423239268Sgonzo
424239268Sgonzo	arm11_context_switch,		/* context_switch	*/
425239268Sgonzo
426239268Sgonzo	pj4bv7_setup			/* cpu setup		*/
427239268Sgonzo};
428239268Sgonzo#endif /* CPU_MV_PJ4B */
429239268Sgonzo
430129198Scognet#if defined(CPU_XSCALE_80200) || defined(CPU_XSCALE_80321) || \
431161592Scognet  defined(CPU_XSCALE_PXA2X0) || defined(CPU_XSCALE_IXP425) || \
432161592Scognet  defined(CPU_XSCALE_80219)
433161592Scognet
434129198Scognetstruct cpu_functions xscale_cpufuncs = {
435129198Scognet	/* CPU functions */
436129198Scognet
437129198Scognet	cpufunc_id,			/* id			*/
438129198Scognet	xscale_cpwait,			/* cpwait		*/
439129198Scognet
440129198Scognet	/* MMU functions */
441129198Scognet
442129198Scognet	xscale_control,			/* control		*/
443129198Scognet	cpufunc_domains,		/* domain		*/
444129198Scognet	xscale_setttb,			/* setttb		*/
445129198Scognet	cpufunc_faultstatus,		/* faultstatus		*/
446129198Scognet	cpufunc_faultaddress,		/* faultaddress		*/
447129198Scognet
448129198Scognet	/* TLB functions */
449129198Scognet
450129198Scognet	armv4_tlb_flushID,		/* tlb_flushID		*/
451129198Scognet	xscale_tlb_flushID_SE,		/* tlb_flushID_SE	*/
452129198Scognet	armv4_tlb_flushI,		/* tlb_flushI		*/
453129198Scognet	(void *)armv4_tlb_flushI,	/* tlb_flushI_SE	*/
454129198Scognet	armv4_tlb_flushD,		/* tlb_flushD		*/
455129198Scognet	armv4_tlb_flushD_SE,		/* tlb_flushD_SE	*/
456129198Scognet
457129198Scognet	/* Cache operations */
458129198Scognet
459129198Scognet	xscale_cache_syncI,		/* icache_sync_all	*/
460129198Scognet	xscale_cache_syncI_rng,		/* icache_sync_range	*/
461129198Scognet
462129198Scognet	xscale_cache_purgeD,		/* dcache_wbinv_all	*/
463129198Scognet	xscale_cache_purgeD_rng,	/* dcache_wbinv_range	*/
464129198Scognet	xscale_cache_flushD_rng,	/* dcache_inv_range	*/
465129198Scognet	xscale_cache_cleanD_rng,	/* dcache_wb_range	*/
466129198Scognet
467266203Sian	xscale_cache_flushID,		/* idcache_inv_all	*/
468129198Scognet	xscale_cache_purgeID,		/* idcache_wbinv_all	*/
469129198Scognet	xscale_cache_purgeID_rng,	/* idcache_wbinv_range	*/
470171618Scognet	cpufunc_nullop,			/* l2cache_wbinv_all 	*/
471171781Scognet	(void *)cpufunc_nullop,		/* l2cache_wbinv_range	*/
472171781Scognet	(void *)cpufunc_nullop,		/* l2cache_inv_range	*/
473171781Scognet	(void *)cpufunc_nullop,		/* l2cache_wb_range	*/
474266387Sian	(void *)cpufunc_nullop,         /* l2cache_drain_writebuf */
475129198Scognet
476129198Scognet	/* Other functions */
477129198Scognet
478129198Scognet	cpufunc_nullop,			/* flush_prefetchbuf	*/
479129198Scognet	armv4_drain_writebuf,		/* drain_writebuf	*/
480129198Scognet	cpufunc_nullop,			/* flush_brnchtgt_C	*/
481129198Scognet	(void *)cpufunc_nullop,		/* flush_brnchtgt_E	*/
482129198Scognet
483129198Scognet	xscale_cpu_sleep,		/* sleep		*/
484129198Scognet
485129198Scognet	/* Soft functions */
486129198Scognet
487129198Scognet	cpufunc_null_fixup,		/* dataabt_fixup	*/
488129198Scognet	cpufunc_null_fixup,		/* prefetchabt_fixup	*/
489129198Scognet
490129198Scognet	xscale_context_switch,		/* context_switch	*/
491129198Scognet
492129198Scognet	xscale_setup			/* cpu setup		*/
493129198Scognet};
494129198Scognet#endif
495161592Scognet/* CPU_XSCALE_80200 || CPU_XSCALE_80321 || CPU_XSCALE_PXA2X0 || CPU_XSCALE_IXP425
496161592Scognet   CPU_XSCALE_80219 */
497129198Scognet
498164080Scognet#ifdef CPU_XSCALE_81342
499164080Scognetstruct cpu_functions xscalec3_cpufuncs = {
500164080Scognet	/* CPU functions */
501164080Scognet
502164080Scognet	cpufunc_id,			/* id			*/
503164080Scognet	xscale_cpwait,			/* cpwait		*/
504164080Scognet
505164080Scognet	/* MMU functions */
506164080Scognet
507164080Scognet	xscale_control,			/* control		*/
508164080Scognet	cpufunc_domains,		/* domain		*/
509164080Scognet	xscalec3_setttb,		/* setttb		*/
510164080Scognet	cpufunc_faultstatus,		/* faultstatus		*/
511164080Scognet	cpufunc_faultaddress,		/* faultaddress		*/
512164080Scognet
513164080Scognet	/* TLB functions */
514164080Scognet
515164080Scognet	armv4_tlb_flushID,		/* tlb_flushID		*/
516164080Scognet	xscale_tlb_flushID_SE,		/* tlb_flushID_SE	*/
517164080Scognet	armv4_tlb_flushI,		/* tlb_flushI		*/
518164080Scognet	(void *)armv4_tlb_flushI,	/* tlb_flushI_SE	*/
519164080Scognet	armv4_tlb_flushD,		/* tlb_flushD		*/
520164080Scognet	armv4_tlb_flushD_SE,		/* tlb_flushD_SE	*/
521164080Scognet
522164080Scognet	/* Cache operations */
523164080Scognet
524164080Scognet	xscalec3_cache_syncI,		/* icache_sync_all	*/
525171618Scognet	xscalec3_cache_syncI_rng,	/* icache_sync_range	*/
526164080Scognet
527164080Scognet	xscalec3_cache_purgeD,		/* dcache_wbinv_all	*/
528164080Scognet	xscalec3_cache_purgeD_rng,	/* dcache_wbinv_range	*/
529164080Scognet	xscale_cache_flushD_rng,	/* dcache_inv_range	*/
530164080Scognet	xscalec3_cache_cleanD_rng,	/* dcache_wb_range	*/
531164080Scognet
532266203Sian	xscale_cache_flushID,		/* idcache_inv_all	*/
533171618Scognet	xscalec3_cache_purgeID,		/* idcache_wbinv_all	*/
534164080Scognet	xscalec3_cache_purgeID_rng,	/* idcache_wbinv_range	*/
535171618Scognet	xscalec3_l2cache_purge,		/* l2cache_wbinv_all	*/
536171618Scognet	xscalec3_l2cache_purge_rng,	/* l2cache_wbinv_range	*/
537171618Scognet	xscalec3_l2cache_flush_rng,	/* l2cache_inv_range	*/
538171618Scognet	xscalec3_l2cache_clean_rng,	/* l2cache_wb_range	*/
539266387Sian	(void *)cpufunc_nullop,         /* l2cache_drain_writebuf */
540164080Scognet
541164080Scognet	/* Other functions */
542164080Scognet
543164080Scognet	cpufunc_nullop,			/* flush_prefetchbuf	*/
544164080Scognet	armv4_drain_writebuf,		/* drain_writebuf	*/
545164080Scognet	cpufunc_nullop,			/* flush_brnchtgt_C	*/
546164080Scognet	(void *)cpufunc_nullop,		/* flush_brnchtgt_E	*/
547164080Scognet
548164080Scognet	xscale_cpu_sleep,		/* sleep		*/
549164080Scognet
550164080Scognet	/* Soft functions */
551164080Scognet
552164080Scognet	cpufunc_null_fixup,		/* dataabt_fixup	*/
553164080Scognet	cpufunc_null_fixup,		/* prefetchabt_fixup	*/
554164080Scognet
555164080Scognet	xscalec3_context_switch,	/* context_switch	*/
556164080Scognet
557164080Scognet	xscale_setup			/* cpu setup		*/
558164080Scognet};
559164080Scognet#endif /* CPU_XSCALE_81342 */
560201468Srpaulo
561201468Srpaulo
562207611Skevlo#if defined(CPU_FA526) || defined(CPU_FA626TE)
563201468Srpaulostruct cpu_functions fa526_cpufuncs = {
564201468Srpaulo	/* CPU functions */
565201468Srpaulo
566207611Skevlo	cpufunc_id,			/* id			*/
567207611Skevlo	cpufunc_nullop,			/* cpwait		*/
568201468Srpaulo
569201468Srpaulo	/* MMU functions */
570201468Srpaulo
571207611Skevlo	cpufunc_control,		/* control		*/
572207611Skevlo	cpufunc_domains,		/* domain		*/
573207611Skevlo	fa526_setttb,			/* setttb		*/
574207611Skevlo	cpufunc_faultstatus,		/* faultstatus		*/
575207611Skevlo	cpufunc_faultaddress,		/* faultaddress		*/
576201468Srpaulo
577201468Srpaulo	/* TLB functions */
578201468Srpaulo
579207611Skevlo	armv4_tlb_flushID,		/* tlb_flushID		*/
580207611Skevlo	fa526_tlb_flushID_SE,		/* tlb_flushID_SE	*/
581207611Skevlo	armv4_tlb_flushI,		/* tlb_flushI		*/
582207611Skevlo	fa526_tlb_flushI_SE,		/* tlb_flushI_SE	*/
583207611Skevlo	armv4_tlb_flushD,		/* tlb_flushD		*/
584207611Skevlo	armv4_tlb_flushD_SE,		/* tlb_flushD_SE	*/
585201468Srpaulo
586201468Srpaulo	/* Cache operations */
587201468Srpaulo
588207611Skevlo	fa526_icache_sync_all,		/* icache_sync_all	*/
589207611Skevlo	fa526_icache_sync_range,	/* icache_sync_range	*/
590201468Srpaulo
591207611Skevlo	fa526_dcache_wbinv_all,		/* dcache_wbinv_all	*/
592207611Skevlo	fa526_dcache_wbinv_range,	/* dcache_wbinv_range	*/
593207611Skevlo	fa526_dcache_inv_range,		/* dcache_inv_range	*/
594207611Skevlo	fa526_dcache_wb_range,		/* dcache_wb_range	*/
595201468Srpaulo
596266203Sian	armv4_idcache_inv_all,		/* idcache_inv_all	*/
597207611Skevlo	fa526_idcache_wbinv_all,	/* idcache_wbinv_all	*/
598207611Skevlo	fa526_idcache_wbinv_range,	/* idcache_wbinv_range	*/
599207611Skevlo	cpufunc_nullop,			/* l2cache_wbinv_all	*/
600207611Skevlo	(void *)cpufunc_nullop,		/* l2cache_wbinv_range	*/
601207611Skevlo	(void *)cpufunc_nullop,		/* l2cache_inv_range	*/
602207611Skevlo	(void *)cpufunc_nullop,		/* l2cache_wb_range	*/
603266387Sian	(void *)cpufunc_nullop,         /* l2cache_drain_writebuf */
604201468Srpaulo
605201468Srpaulo	/* Other functions */
606201468Srpaulo
607207611Skevlo	fa526_flush_prefetchbuf,	/* flush_prefetchbuf	*/
608207611Skevlo	armv4_drain_writebuf,		/* drain_writebuf	*/
609207611Skevlo	cpufunc_nullop,			/* flush_brnchtgt_C	*/
610207611Skevlo	fa526_flush_brnchtgt_E,		/* flush_brnchtgt_E	*/
611201468Srpaulo
612207611Skevlo	fa526_cpu_sleep,		/* sleep		*/
613201468Srpaulo
614201468Srpaulo	/* Soft functions */
615201468Srpaulo
616207611Skevlo	cpufunc_null_fixup,		/* dataabt_fixup	*/
617207611Skevlo	cpufunc_null_fixup,		/* prefetchabt_fixup	*/
618201468Srpaulo
619207611Skevlo	fa526_context_switch,		/* context_switch	*/
620201468Srpaulo
621207611Skevlo	fa526_setup			/* cpu setup 		*/
622236991Simp};
623207611Skevlo#endif	/* CPU_FA526 || CPU_FA626TE */
624201468Srpaulo
625244480Sgonzo#if defined(CPU_ARM1136)
626244480Sgonzostruct cpu_functions arm1136_cpufuncs = {
627239701Sgonzo	/* CPU functions */
628239701Sgonzo
629239701Sgonzo	cpufunc_id,                     /* id                   */
630244480Sgonzo	cpufunc_nullop,                 /* cpwait               */
631239701Sgonzo
632239701Sgonzo	/* MMU functions */
633239701Sgonzo
634239701Sgonzo	cpufunc_control,                /* control              */
635239701Sgonzo	cpufunc_domains,                /* Domain               */
636244480Sgonzo	arm11x6_setttb,                 /* Setttb               */
637239701Sgonzo	cpufunc_faultstatus,            /* Faultstatus          */
638239701Sgonzo	cpufunc_faultaddress,           /* Faultaddress         */
639239701Sgonzo
640239701Sgonzo	/* TLB functions */
641239701Sgonzo
642239701Sgonzo	arm11_tlb_flushID,              /* tlb_flushID          */
643239701Sgonzo	arm11_tlb_flushID_SE,           /* tlb_flushID_SE       */
644239701Sgonzo	arm11_tlb_flushI,               /* tlb_flushI           */
645239701Sgonzo	arm11_tlb_flushI_SE,            /* tlb_flushI_SE        */
646239701Sgonzo	arm11_tlb_flushD,               /* tlb_flushD           */
647239701Sgonzo	arm11_tlb_flushD_SE,            /* tlb_flushD_SE        */
648239701Sgonzo
649239701Sgonzo	/* Cache operations */
650239701Sgonzo
651244480Sgonzo	arm11x6_icache_sync_all,        /* icache_sync_all      */
652244480Sgonzo	arm11x6_icache_sync_range,      /* icache_sync_range    */
653239701Sgonzo
654244480Sgonzo	arm11x6_dcache_wbinv_all,       /* dcache_wbinv_all     */
655239701Sgonzo	armv6_dcache_wbinv_range,       /* dcache_wbinv_range   */
656239701Sgonzo	armv6_dcache_inv_range,         /* dcache_inv_range     */
657239701Sgonzo	armv6_dcache_wb_range,          /* dcache_wb_range      */
658239701Sgonzo
659266203Sian	armv6_idcache_inv_all,		/* idcache_inv_all	*/
660244480Sgonzo	arm11x6_idcache_wbinv_all,      /* idcache_wbinv_all    */
661244480Sgonzo	arm11x6_idcache_wbinv_range,    /* idcache_wbinv_range  */
662239701Sgonzo
663244480Sgonzo	(void *)cpufunc_nullop,         /* l2cache_wbinv_all    */
664239701Sgonzo	(void *)cpufunc_nullop,         /* l2cache_wbinv_range  */
665239701Sgonzo	(void *)cpufunc_nullop,         /* l2cache_inv_range    */
666239701Sgonzo	(void *)cpufunc_nullop,         /* l2cache_wb_range     */
667266387Sian	(void *)cpufunc_nullop,         /* l2cache_drain_writebuf */
668239701Sgonzo
669239701Sgonzo	/* Other functions */
670239701Sgonzo
671244480Sgonzo	arm11x6_flush_prefetchbuf,      /* flush_prefetchbuf    */
672239701Sgonzo	arm11_drain_writebuf,           /* drain_writebuf       */
673239701Sgonzo	cpufunc_nullop,                 /* flush_brnchtgt_C     */
674239701Sgonzo	(void *)cpufunc_nullop,         /* flush_brnchtgt_E     */
675239701Sgonzo
676244480Sgonzo	arm11_sleep,                  	/* sleep                */
677239701Sgonzo
678239701Sgonzo	/* Soft functions */
679239701Sgonzo
680239701Sgonzo	cpufunc_null_fixup,             /* dataabt_fixup        */
681239701Sgonzo	cpufunc_null_fixup,             /* prefetchabt_fixup    */
682239701Sgonzo
683239701Sgonzo	arm11_context_switch,           /* context_switch       */
684239701Sgonzo
685244480Sgonzo	arm11x6_setup                   /* cpu setup            */
686239701Sgonzo};
687244480Sgonzo#endif /* CPU_ARM1136 */
688244480Sgonzo#if defined(CPU_ARM1176)
689244480Sgonzostruct cpu_functions arm1176_cpufuncs = {
690244480Sgonzo	/* CPU functions */
691244480Sgonzo
692244480Sgonzo	cpufunc_id,                     /* id                   */
693244480Sgonzo	cpufunc_nullop,                 /* cpwait               */
694244480Sgonzo
695244480Sgonzo	/* MMU functions */
696244480Sgonzo
697244480Sgonzo	cpufunc_control,                /* control              */
698244480Sgonzo	cpufunc_domains,                /* Domain               */
699244480Sgonzo	arm11x6_setttb,                 /* Setttb               */
700244480Sgonzo	cpufunc_faultstatus,            /* Faultstatus          */
701244480Sgonzo	cpufunc_faultaddress,           /* Faultaddress         */
702244480Sgonzo
703244480Sgonzo	/* TLB functions */
704244480Sgonzo
705244480Sgonzo	arm11_tlb_flushID,              /* tlb_flushID          */
706244480Sgonzo	arm11_tlb_flushID_SE,           /* tlb_flushID_SE       */
707244480Sgonzo	arm11_tlb_flushI,               /* tlb_flushI           */
708244480Sgonzo	arm11_tlb_flushI_SE,            /* tlb_flushI_SE        */
709244480Sgonzo	arm11_tlb_flushD,               /* tlb_flushD           */
710244480Sgonzo	arm11_tlb_flushD_SE,            /* tlb_flushD_SE        */
711244480Sgonzo
712244480Sgonzo	/* Cache operations */
713244480Sgonzo
714244480Sgonzo	arm11x6_icache_sync_all,        /* icache_sync_all      */
715244480Sgonzo	arm11x6_icache_sync_range,      /* icache_sync_range    */
716244480Sgonzo
717244480Sgonzo	arm11x6_dcache_wbinv_all,       /* dcache_wbinv_all     */
718244480Sgonzo	armv6_dcache_wbinv_range,       /* dcache_wbinv_range   */
719244480Sgonzo	armv6_dcache_inv_range,         /* dcache_inv_range     */
720244480Sgonzo	armv6_dcache_wb_range,          /* dcache_wb_range      */
721244480Sgonzo
722266203Sian	armv6_idcache_inv_all,		/* idcache_inv_all	*/
723244480Sgonzo	arm11x6_idcache_wbinv_all,      /* idcache_wbinv_all    */
724244480Sgonzo	arm11x6_idcache_wbinv_range,    /* idcache_wbinv_range  */
725244480Sgonzo
726244480Sgonzo	(void *)cpufunc_nullop,         /* l2cache_wbinv_all    */
727244480Sgonzo	(void *)cpufunc_nullop,         /* l2cache_wbinv_range  */
728244480Sgonzo	(void *)cpufunc_nullop,         /* l2cache_inv_range    */
729244480Sgonzo	(void *)cpufunc_nullop,         /* l2cache_wb_range     */
730266387Sian	(void *)cpufunc_nullop,         /* l2cache_drain_writebuf */
731244480Sgonzo
732244480Sgonzo	/* Other functions */
733244480Sgonzo
734244480Sgonzo	arm11x6_flush_prefetchbuf,      /* flush_prefetchbuf    */
735244480Sgonzo	arm11_drain_writebuf,           /* drain_writebuf       */
736244480Sgonzo	cpufunc_nullop,                 /* flush_brnchtgt_C     */
737244480Sgonzo	(void *)cpufunc_nullop,         /* flush_brnchtgt_E     */
738244480Sgonzo
739244480Sgonzo	arm11x6_sleep,                  /* sleep                */
740244480Sgonzo
741244480Sgonzo	/* Soft functions */
742244480Sgonzo
743244480Sgonzo	cpufunc_null_fixup,             /* dataabt_fixup        */
744244480Sgonzo	cpufunc_null_fixup,             /* prefetchabt_fixup    */
745244480Sgonzo
746244480Sgonzo	arm11_context_switch,           /* context_switch       */
747244480Sgonzo
748244480Sgonzo	arm11x6_setup                   /* cpu setup            */
749244480Sgonzo};
750244480Sgonzo#endif /*CPU_ARM1176 */
751239701Sgonzo
752266058Sian#if defined(CPU_CORTEXA) || defined(CPU_KRAIT)
753239268Sgonzostruct cpu_functions cortexa_cpufuncs = {
754239268Sgonzo	/* CPU functions */
755239268Sgonzo
756239268Sgonzo	cpufunc_id,                     /* id                   */
757239268Sgonzo	cpufunc_nullop,                 /* cpwait               */
758239268Sgonzo
759239268Sgonzo	/* MMU functions */
760239268Sgonzo
761239268Sgonzo	cpufunc_control,                /* control              */
762239268Sgonzo	cpufunc_domains,                /* Domain               */
763239268Sgonzo	armv7_setttb,                   /* Setttb               */
764239268Sgonzo	cpufunc_faultstatus,            /* Faultstatus          */
765239268Sgonzo	cpufunc_faultaddress,           /* Faultaddress         */
766239268Sgonzo
767266332Sian	/*
768266332Sian	 * TLB functions.  ARMv7 does all TLB ops based on a unified TLB model
769266332Sian	 * whether the hardware implements separate I+D or not, so we use the
770266332Sian	 * same 'ID' functions for all 3 variations.
771266332Sian	 */
772239268Sgonzo
773243024Scognet	armv7_tlb_flushID,              /* tlb_flushID          */
774239268Sgonzo	armv7_tlb_flushID_SE,           /* tlb_flushID_SE       */
775266332Sian	armv7_tlb_flushID,              /* tlb_flushI           */
776266332Sian	armv7_tlb_flushID_SE,           /* tlb_flushI_SE        */
777266332Sian	armv7_tlb_flushID,              /* tlb_flushD           */
778266332Sian	armv7_tlb_flushID_SE,           /* tlb_flushD_SE        */
779239268Sgonzo
780239268Sgonzo	/* Cache operations */
781239268Sgonzo
782266373Sian	armv7_icache_sync_all, 	        /* icache_sync_all      */
783239268Sgonzo	armv7_icache_sync_range,        /* icache_sync_range    */
784239268Sgonzo
785239268Sgonzo	armv7_dcache_wbinv_all,         /* dcache_wbinv_all     */
786239268Sgonzo	armv7_dcache_wbinv_range,       /* dcache_wbinv_range   */
787239268Sgonzo	armv7_dcache_inv_range,         /* dcache_inv_range     */
788239268Sgonzo	armv7_dcache_wb_range,          /* dcache_wb_range      */
789239268Sgonzo
790266203Sian	armv7_idcache_inv_all,		/* idcache_inv_all	*/
791239268Sgonzo	armv7_idcache_wbinv_all,        /* idcache_wbinv_all    */
792239268Sgonzo	armv7_idcache_wbinv_range,      /* idcache_wbinv_range  */
793239268Sgonzo
794243026Scognet	/*
795243026Scognet	 * Note: For CPUs using the PL310 the L2 ops are filled in when the
796239268Sgonzo	 * L2 cache controller is actually enabled.
797239268Sgonzo	 */
798239268Sgonzo	cpufunc_nullop,                 /* l2cache_wbinv_all    */
799239268Sgonzo	(void *)cpufunc_nullop,         /* l2cache_wbinv_range  */
800239268Sgonzo	(void *)cpufunc_nullop,         /* l2cache_inv_range    */
801239268Sgonzo	(void *)cpufunc_nullop,         /* l2cache_wb_range     */
802266387Sian	(void *)cpufunc_nullop,         /* l2cache_drain_writebuf */
803239268Sgonzo
804239268Sgonzo	/* Other functions */
805239268Sgonzo
806239268Sgonzo	cpufunc_nullop,                 /* flush_prefetchbuf    */
807245478Scognet	armv7_drain_writebuf,           /* drain_writebuf       */
808239268Sgonzo	cpufunc_nullop,                 /* flush_brnchtgt_C     */
809239268Sgonzo	(void *)cpufunc_nullop,         /* flush_brnchtgt_E     */
810239268Sgonzo
811266207Sian	armv7_sleep,                    /* sleep                */
812239268Sgonzo
813239268Sgonzo	/* Soft functions */
814239268Sgonzo
815239268Sgonzo	cpufunc_null_fixup,             /* dataabt_fixup        */
816239268Sgonzo	cpufunc_null_fixup,             /* prefetchabt_fixup    */
817239268Sgonzo
818245478Scognet	armv7_context_switch,           /* context_switch       */
819239268Sgonzo
820239268Sgonzo	cortexa_setup                     /* cpu setup            */
821239268Sgonzo};
822239268Sgonzo#endif /* CPU_CORTEXA */
823201468Srpaulo
824129198Scognet/*
825129198Scognet * Global constants also used by locore.s
826129198Scognet */
827129198Scognet
828129198Scognetstruct cpu_functions cpufuncs;
829129198Scognetu_int cputype;
830129198Scognetu_int cpu_reset_needs_v4_MMU_disable;	/* flag used in locore.s */
831129198Scognet
832266311Sian#if defined(CPU_ARM9) ||	\
833244480Sgonzo  defined (CPU_ARM9E) || defined (CPU_ARM10) || defined (CPU_ARM1136) ||	\
834244480Sgonzo  defined(CPU_ARM1176) || defined(CPU_XSCALE_80200) || defined(CPU_XSCALE_80321) ||		\
835207611Skevlo  defined(CPU_XSCALE_PXA2X0) || defined(CPU_XSCALE_IXP425) ||		\
836239268Sgonzo  defined(CPU_FA526) || defined(CPU_FA626TE) || defined(CPU_MV_PJ4B) ||			\
837239268Sgonzo  defined(CPU_XSCALE_80219) || defined(CPU_XSCALE_81342) || \
838266058Sian  defined(CPU_CORTEXA) || defined(CPU_KRAIT)
839161592Scognet
840137498Strhodesstatic void get_cachetype_cp15(void);
841129198Scognet
842129198Scognet/* Additional cache information local to this file.  Log2 of some of the
843129198Scognet   above numbers.  */
844129198Scognetstatic int	arm_dcache_l2_nsets;
845129198Scognetstatic int	arm_dcache_l2_assoc;
846129198Scognetstatic int	arm_dcache_l2_linesize;
847129198Scognet
848129198Scognetstatic void
849129198Scognetget_cachetype_cp15()
850129198Scognet{
851239268Sgonzo	u_int ctype, isize, dsize, cpuid;
852239268Sgonzo	u_int clevel, csize, i, sel;
853129198Scognet	u_int multiplier;
854239268Sgonzo	u_char type;
855129198Scognet
856129198Scognet	__asm __volatile("mrc p15, 0, %0, c0, c0, 1"
857129198Scognet		: "=r" (ctype));
858129198Scognet
859239268Sgonzo	cpuid = cpufunc_id();
860129198Scognet	/*
861129198Scognet	 * ...and thus spake the ARM ARM:
862129198Scognet	 *
863129198Scognet	 * If an <opcode2> value corresponding to an unimplemented or
864129198Scognet	 * reserved ID register is encountered, the System Control
865129198Scognet	 * processor returns the value of the main ID register.
866129198Scognet	 */
867239268Sgonzo	if (ctype == cpuid)
868129198Scognet		goto out;
869129198Scognet
870239268Sgonzo	if (CPU_CT_FORMAT(ctype) == CPU_CT_ARMV7) {
871239268Sgonzo		__asm __volatile("mrc p15, 1, %0, c0, c0, 1"
872239268Sgonzo		    : "=r" (clevel));
873239268Sgonzo		arm_cache_level = clevel;
874239268Sgonzo		arm_cache_loc = CPU_CLIDR_LOC(arm_cache_level);
875239268Sgonzo		i = 0;
876239268Sgonzo		while ((type = (clevel & 0x7)) && i < 7) {
877239268Sgonzo			if (type == CACHE_DCACHE || type == CACHE_UNI_CACHE ||
878239268Sgonzo			    type == CACHE_SEP_CACHE) {
879239268Sgonzo				sel = i << 1;
880239268Sgonzo				__asm __volatile("mcr p15, 2, %0, c0, c0, 0"
881239268Sgonzo				    : : "r" (sel));
882239268Sgonzo				__asm __volatile("mrc p15, 1, %0, c0, c0, 0"
883239268Sgonzo				    : "=r" (csize));
884239268Sgonzo				arm_cache_type[sel] = csize;
885239268Sgonzo				arm_dcache_align = 1 <<
886239268Sgonzo				    (CPUV7_CT_xSIZE_LEN(csize) + 4);
887239268Sgonzo				arm_dcache_align_mask = arm_dcache_align - 1;
888239268Sgonzo			}
889239268Sgonzo			if (type == CACHE_ICACHE || type == CACHE_SEP_CACHE) {
890239268Sgonzo				sel = (i << 1) | 1;
891239268Sgonzo				__asm __volatile("mcr p15, 2, %0, c0, c0, 0"
892239268Sgonzo				    : : "r" (sel));
893239268Sgonzo				__asm __volatile("mrc p15, 1, %0, c0, c0, 0"
894239268Sgonzo				    : "=r" (csize));
895239268Sgonzo				arm_cache_type[sel] = csize;
896239268Sgonzo			}
897239268Sgonzo			i++;
898239268Sgonzo			clevel >>= 3;
899239268Sgonzo		}
900239268Sgonzo	} else {
901239268Sgonzo		if ((ctype & CPU_CT_S) == 0)
902239268Sgonzo			arm_pcache_unified = 1;
903129198Scognet
904239268Sgonzo		/*
905239268Sgonzo		 * If you want to know how this code works, go read the ARM ARM.
906239268Sgonzo		 */
907129198Scognet
908239268Sgonzo		arm_pcache_type = CPU_CT_CTYPE(ctype);
909129198Scognet
910239268Sgonzo		if (arm_pcache_unified == 0) {
911239268Sgonzo			isize = CPU_CT_ISIZE(ctype);
912239268Sgonzo			multiplier = (isize & CPU_CT_xSIZE_M) ? 3 : 2;
913239268Sgonzo			arm_picache_line_size = 1U << (CPU_CT_xSIZE_LEN(isize) + 3);
914239268Sgonzo			if (CPU_CT_xSIZE_ASSOC(isize) == 0) {
915239268Sgonzo				if (isize & CPU_CT_xSIZE_M)
916239268Sgonzo					arm_picache_line_size = 0; /* not present */
917239268Sgonzo				else
918239268Sgonzo					arm_picache_ways = 1;
919239268Sgonzo			} else {
920239268Sgonzo				arm_picache_ways = multiplier <<
921239268Sgonzo				    (CPU_CT_xSIZE_ASSOC(isize) - 1);
922239268Sgonzo			}
923239268Sgonzo			arm_picache_size = multiplier << (CPU_CT_xSIZE_SIZE(isize) + 8);
924239268Sgonzo		}
925239268Sgonzo
926239268Sgonzo		dsize = CPU_CT_DSIZE(ctype);
927239268Sgonzo		multiplier = (dsize & CPU_CT_xSIZE_M) ? 3 : 2;
928239268Sgonzo		arm_pdcache_line_size = 1U << (CPU_CT_xSIZE_LEN(dsize) + 3);
929239268Sgonzo		if (CPU_CT_xSIZE_ASSOC(dsize) == 0) {
930239268Sgonzo			if (dsize & CPU_CT_xSIZE_M)
931239268Sgonzo				arm_pdcache_line_size = 0; /* not present */
932129198Scognet			else
933239268Sgonzo				arm_pdcache_ways = 1;
934129198Scognet		} else {
935239268Sgonzo			arm_pdcache_ways = multiplier <<
936239268Sgonzo			    (CPU_CT_xSIZE_ASSOC(dsize) - 1);
937129198Scognet		}
938239268Sgonzo		arm_pdcache_size = multiplier << (CPU_CT_xSIZE_SIZE(dsize) + 8);
939129198Scognet
940239268Sgonzo		arm_dcache_align = arm_pdcache_line_size;
941129198Scognet
942239268Sgonzo		arm_dcache_l2_assoc = CPU_CT_xSIZE_ASSOC(dsize) + multiplier - 2;
943239268Sgonzo		arm_dcache_l2_linesize = CPU_CT_xSIZE_LEN(dsize) + 3;
944239268Sgonzo		arm_dcache_l2_nsets = 6 + CPU_CT_xSIZE_SIZE(dsize) -
945239268Sgonzo		    CPU_CT_xSIZE_ASSOC(dsize) - CPU_CT_xSIZE_LEN(dsize);
946129198Scognet
947239268Sgonzo	out:
948239268Sgonzo		arm_dcache_align_mask = arm_dcache_align - 1;
949239268Sgonzo	}
950129198Scognet}
951266311Sian#endif /* ARM9 || XSCALE */
952129198Scognet
953129198Scognet/*
954129198Scognet * Cannot panic here as we may not have a console yet ...
955129198Scognet */
956129198Scognet
957129198Scognetint
958129198Scognetset_cpufuncs()
959129198Scognet{
960129198Scognet	cputype = cpufunc_id();
961129198Scognet	cputype &= CPU_ID_CPU_MASK;
962129198Scognet
963129198Scognet	/*
964129198Scognet	 * NOTE: cpu_do_powersave defaults to off.  If we encounter a
965129198Scognet	 * CPU type where we want to use it by default, then we set it.
966129198Scognet	 */
967129198Scognet
968129198Scognet#ifdef CPU_ARM9
969129198Scognet	if (((cputype & CPU_ID_IMPLEMENTOR_MASK) == CPU_ID_ARM_LTD ||
970129198Scognet	     (cputype & CPU_ID_IMPLEMENTOR_MASK) == CPU_ID_TI) &&
971129198Scognet	    (cputype & 0x0000f000) == 0x00009000) {
972129198Scognet		cpufuncs = arm9_cpufuncs;
973129198Scognet		cpu_reset_needs_v4_MMU_disable = 1;	/* V4 or higher */
974129198Scognet		get_cachetype_cp15();
975146605Scognet		arm9_dcache_sets_inc = 1U << arm_dcache_l2_linesize;
976146605Scognet		arm9_dcache_sets_max = (1U << (arm_dcache_l2_linesize +
977146605Scognet		    arm_dcache_l2_nsets)) - arm9_dcache_sets_inc;
978146605Scognet		arm9_dcache_index_inc = 1U << (32 - arm_dcache_l2_assoc);
979146605Scognet		arm9_dcache_index_max = 0U - arm9_dcache_index_inc;
980137270Scognet#ifdef ARM9_CACHE_WRITE_THROUGH
981129198Scognet		pmap_pte_init_arm9();
982137270Scognet#else
983137270Scognet		pmap_pte_init_generic();
984137270Scognet#endif
985166655Scognet		goto out;
986129198Scognet	}
987129198Scognet#endif /* CPU_ARM9 */
988172738Simp#if defined(CPU_ARM9E) || defined(CPU_ARM10)
989239268Sgonzo	if (cputype == CPU_ID_MV88FR131 || cputype == CPU_ID_MV88FR571_VD ||
990183835Sraj	    cputype == CPU_ID_MV88FR571_41) {
991239268Sgonzo		uint32_t sheeva_ctrl;
992183835Sraj
993239268Sgonzo		sheeva_ctrl = (MV_DC_STREAM_ENABLE | MV_BTB_DISABLE |
994239268Sgonzo		    MV_L2_ENABLE);
995239268Sgonzo		/*
996239268Sgonzo		 * Workaround for Marvell MV78100 CPU: Cache prefetch
997239268Sgonzo		 * mechanism may affect the cache coherency validity,
998239268Sgonzo		 * so it needs to be disabled.
999239268Sgonzo		 *
1000239268Sgonzo		 * Refer to errata document MV-S501058-00C.pdf (p. 3.1
1001239268Sgonzo		 * L2 Prefetching Mechanism) for details.
1002239268Sgonzo		 */
1003239268Sgonzo		if (cputype == CPU_ID_MV88FR571_VD ||
1004239268Sgonzo		    cputype == CPU_ID_MV88FR571_41)
1005239268Sgonzo			sheeva_ctrl |= MV_L2_PREFETCH_DISABLE;
1006212825Smav
1007239268Sgonzo		sheeva_control_ext(0xffffffff & ~MV_WA_ENABLE, sheeva_ctrl);
1008183835Sraj
1009239268Sgonzo		cpufuncs = sheeva_cpufuncs;
1010172738Simp		get_cachetype_cp15();
1011172738Simp		pmap_pte_init_generic();
1012174058Scognet		goto out;
1013239268Sgonzo	} else if (cputype == CPU_ID_ARM926EJS || cputype == CPU_ID_ARM1026EJS) {
1014239268Sgonzo		cpufuncs = armv5_ec_cpufuncs;
1015239268Sgonzo		get_cachetype_cp15();
1016239268Sgonzo		pmap_pte_init_generic();
1017239268Sgonzo		goto out;
1018172738Simp	}
1019172738Simp#endif /* CPU_ARM9E || CPU_ARM10 */
1020129198Scognet#ifdef CPU_ARM10
1021129198Scognet	if (/* cputype == CPU_ID_ARM1020T || */
1022129198Scognet	    cputype == CPU_ID_ARM1020E) {
1023129198Scognet		/*
1024129198Scognet		 * Select write-through cacheing (this isn't really an
1025129198Scognet		 * option on ARM1020T).
1026129198Scognet		 */
1027129198Scognet		cpufuncs = arm10_cpufuncs;
1028129198Scognet		cpu_reset_needs_v4_MMU_disable = 1;	/* V4 or higher */
1029129198Scognet		get_cachetype_cp15();
1030129198Scognet		arm10_dcache_sets_inc = 1U << arm_dcache_l2_linesize;
1031236991Simp		arm10_dcache_sets_max =
1032129198Scognet		    (1U << (arm_dcache_l2_linesize + arm_dcache_l2_nsets)) -
1033129198Scognet		    arm10_dcache_sets_inc;
1034129198Scognet		arm10_dcache_index_inc = 1U << (32 - arm_dcache_l2_assoc);
1035129198Scognet		arm10_dcache_index_max = 0U - arm10_dcache_index_inc;
1036129198Scognet		pmap_pte_init_generic();
1037166655Scognet		goto out;
1038129198Scognet	}
1039129198Scognet#endif /* CPU_ARM10 */
1040244480Sgonzo#if defined(CPU_ARM1136) || defined(CPU_ARM1176)
1041244480Sgonzo	if (cputype == CPU_ID_ARM1136JS
1042244480Sgonzo	    || cputype == CPU_ID_ARM1136JSR1
1043244480Sgonzo	    || cputype == CPU_ID_ARM1176JZS) {
1044244480Sgonzo#ifdef CPU_ARM1136
1045244480Sgonzo		if (cputype == CPU_ID_ARM1136JS
1046244480Sgonzo		    || cputype == CPU_ID_ARM1136JSR1)
1047244480Sgonzo			cpufuncs = arm1136_cpufuncs;
1048244480Sgonzo#endif
1049244480Sgonzo#ifdef CPU_ARM1176
1050244480Sgonzo		if (cputype == CPU_ID_ARM1176JZS)
1051244480Sgonzo			cpufuncs = arm1176_cpufuncs;
1052244480Sgonzo#endif
1053244480Sgonzo		cpu_reset_needs_v4_MMU_disable = 1;     /* V4 or higher */
1054244480Sgonzo		get_cachetype_cp15();
1055239701Sgonzo
1056244480Sgonzo		pmap_pte_init_mmu_v6();
1057244480Sgonzo
1058244480Sgonzo		goto out;
1059244480Sgonzo	}
1060244480Sgonzo#endif /* CPU_ARM1136 || CPU_ARM1176 */
1061266058Sian#if defined(CPU_CORTEXA) || defined(CPU_KRAIT)
1062253857Sganbold	if (cputype == CPU_ID_CORTEXA7 ||
1063253857Sganbold	    cputype == CPU_ID_CORTEXA8R1 ||
1064239268Sgonzo	    cputype == CPU_ID_CORTEXA8R2 ||
1065239268Sgonzo	    cputype == CPU_ID_CORTEXA8R3 ||
1066239268Sgonzo	    cputype == CPU_ID_CORTEXA9R1 ||
1067249999Swkoszek	    cputype == CPU_ID_CORTEXA9R2 ||
1068252361Sray	    cputype == CPU_ID_CORTEXA9R3 ||
1069266341Sian	    cputype == CPU_ID_CORTEXA15R0 ||
1070266341Sian	    cputype == CPU_ID_CORTEXA15R1 ||
1071266341Sian	    cputype == CPU_ID_CORTEXA15R2 ||
1072266341Sian	    cputype == CPU_ID_CORTEXA15R3 ||
1073266058Sian	    cputype == CPU_ID_KRAIT ) {
1074239268Sgonzo		cpufuncs = cortexa_cpufuncs;
1075239268Sgonzo		cpu_reset_needs_v4_MMU_disable = 1;     /* V4 or higher */
1076239268Sgonzo		get_cachetype_cp15();
1077239268Sgonzo
1078239268Sgonzo		pmap_pte_init_mmu_v6();
1079239268Sgonzo		/* Use powersave on this CPU. */
1080239268Sgonzo		cpu_do_powersave = 1;
1081239268Sgonzo		goto out;
1082239268Sgonzo	}
1083239268Sgonzo#endif /* CPU_CORTEXA */
1084239268Sgonzo
1085239268Sgonzo#if defined(CPU_MV_PJ4B)
1086266046Sian	if (cputype == CPU_ID_MV88SV581X_V7 ||
1087240486Sgber	    cputype == CPU_ID_MV88SV584X_V7 ||
1088239268Sgonzo	    cputype == CPU_ID_ARM_88SV581X_V7) {
1089266046Sian		cpufuncs = pj4bv7_cpufuncs;
1090239268Sgonzo		get_cachetype_cp15();
1091239268Sgonzo		pmap_pte_init_mmu_v6();
1092239268Sgonzo		goto out;
1093239268Sgonzo	}
1094239268Sgonzo#endif /* CPU_MV_PJ4B */
1095129198Scognet
1096207611Skevlo#if defined(CPU_FA526) || defined(CPU_FA626TE)
1097207611Skevlo	if (cputype == CPU_ID_FA526 || cputype == CPU_ID_FA626TE) {
1098201468Srpaulo		cpufuncs = fa526_cpufuncs;
1099201468Srpaulo		cpu_reset_needs_v4_MMU_disable = 1;	/* SA needs it	*/
1100201468Srpaulo		get_cachetype_cp15();
1101201468Srpaulo		pmap_pte_init_generic();
1102201468Srpaulo
1103201468Srpaulo		/* Use powersave on this CPU. */
1104201468Srpaulo		cpu_do_powersave = 1;
1105201468Srpaulo
1106201468Srpaulo		goto out;
1107201468Srpaulo	}
1108207611Skevlo#endif	/* CPU_FA526 || CPU_FA626TE */
1109266311Sian
1110129198Scognet#ifdef CPU_XSCALE_80200
1111129198Scognet	if (cputype == CPU_ID_80200) {
1112129198Scognet		int rev = cpufunc_id() & CPU_ID_REVISION_MASK;
1113129198Scognet
1114129198Scognet		i80200_icu_init();
1115129198Scognet
1116129198Scognet#if defined(XSCALE_CCLKCFG)
1117129198Scognet		/*
1118129198Scognet		 * Crank CCLKCFG to maximum legal value.
1119129198Scognet		 */
1120129198Scognet		__asm __volatile ("mcr p14, 0, %0, c6, c0, 0"
1121129198Scognet			:
1122129198Scognet			: "r" (XSCALE_CCLKCFG));
1123129198Scognet#endif
1124129198Scognet
1125129198Scognet		/*
1126129198Scognet		 * XXX Disable ECC in the Bus Controller Unit; we
1127129198Scognet		 * don't really support it, yet.  Clear any pending
1128129198Scognet		 * error indications.
1129129198Scognet		 */
1130129198Scognet		__asm __volatile("mcr p13, 0, %0, c0, c1, 0"
1131129198Scognet			:
1132129198Scognet			: "r" (BCUCTL_E0|BCUCTL_E1|BCUCTL_EV));
1133129198Scognet
1134129198Scognet		cpufuncs = xscale_cpufuncs;
1135129198Scognet		/*
1136129198Scognet		 * i80200 errata: Step-A0 and A1 have a bug where
1137129198Scognet		 * D$ dirty bits are not cleared on "invalidate by
1138129198Scognet		 * address".
1139129198Scognet		 *
1140129198Scognet		 * Workaround: Clean cache line before invalidating.
1141129198Scognet		 */
1142129198Scognet		if (rev == 0 || rev == 1)
1143129198Scognet			cpufuncs.cf_dcache_inv_range = xscale_cache_purgeD_rng;
1144129198Scognet
1145129198Scognet		cpu_reset_needs_v4_MMU_disable = 1;	/* XScale needs it */
1146129198Scognet		get_cachetype_cp15();
1147129198Scognet		pmap_pte_init_xscale();
1148166655Scognet		goto out;
1149129198Scognet	}
1150129198Scognet#endif /* CPU_XSCALE_80200 */
1151161592Scognet#if defined(CPU_XSCALE_80321) || defined(CPU_XSCALE_80219)
1152129198Scognet	if (cputype == CPU_ID_80321_400 || cputype == CPU_ID_80321_600 ||
1153161592Scognet	    cputype == CPU_ID_80321_400_B0 || cputype == CPU_ID_80321_600_B0 ||
1154161592Scognet	    cputype == CPU_ID_80219_400 || cputype == CPU_ID_80219_600) {
1155129198Scognet		cpufuncs = xscale_cpufuncs;
1156129198Scognet		cpu_reset_needs_v4_MMU_disable = 1;	/* XScale needs it */
1157129198Scognet		get_cachetype_cp15();
1158129198Scognet		pmap_pte_init_xscale();
1159166655Scognet		goto out;
1160129198Scognet	}
1161129198Scognet#endif /* CPU_XSCALE_80321 */
1162161592Scognet
1163164080Scognet#if defined(CPU_XSCALE_81342)
1164164080Scognet	if (cputype == CPU_ID_81342) {
1165164080Scognet		cpufuncs = xscalec3_cpufuncs;
1166164080Scognet		cpu_reset_needs_v4_MMU_disable = 1;	/* XScale needs it */
1167164080Scognet		get_cachetype_cp15();
1168164080Scognet		pmap_pte_init_xscale();
1169166655Scognet		goto out;
1170164080Scognet	}
1171164080Scognet#endif /* CPU_XSCALE_81342 */
1172129198Scognet#ifdef CPU_XSCALE_PXA2X0
1173129198Scognet	/* ignore core revision to test PXA2xx CPUs */
1174129198Scognet	if ((cputype & ~CPU_ID_XSCALE_COREREV_MASK) == CPU_ID_PXA250 ||
1175191817Sstas	    (cputype & ~CPU_ID_XSCALE_COREREV_MASK) == CPU_ID_PXA27X ||
1176129198Scognet	    (cputype & ~CPU_ID_XSCALE_COREREV_MASK) == CPU_ID_PXA210) {
1177129198Scognet
1178129198Scognet		cpufuncs = xscale_cpufuncs;
1179129198Scognet		cpu_reset_needs_v4_MMU_disable = 1;	/* XScale needs it */
1180129198Scognet		get_cachetype_cp15();
1181129198Scognet		pmap_pte_init_xscale();
1182129198Scognet
1183129198Scognet		/* Use powersave on this CPU. */
1184129198Scognet		cpu_do_powersave = 1;
1185129198Scognet
1186166655Scognet		goto out;
1187129198Scognet	}
1188129198Scognet#endif /* CPU_XSCALE_PXA2X0 */
1189129198Scognet#ifdef CPU_XSCALE_IXP425
1190129198Scognet	if (cputype == CPU_ID_IXP425_533 || cputype == CPU_ID_IXP425_400 ||
1191186352Ssam            cputype == CPU_ID_IXP425_266 || cputype == CPU_ID_IXP435) {
1192129198Scognet
1193129198Scognet		cpufuncs = xscale_cpufuncs;
1194129198Scognet		cpu_reset_needs_v4_MMU_disable = 1;	/* XScale needs it */
1195129198Scognet		get_cachetype_cp15();
1196129198Scognet		pmap_pte_init_xscale();
1197129198Scognet
1198166655Scognet		goto out;
1199129198Scognet	}
1200129198Scognet#endif /* CPU_XSCALE_IXP425 */
1201129198Scognet	/*
1202129198Scognet	 * Bzzzz. And the answer was ...
1203129198Scognet	 */
1204129198Scognet	panic("No support for this CPU type (%08x) in kernel", cputype);
1205129198Scognet	return(ARCHITECTURE_NOT_PRESENT);
1206166655Scognetout:
1207166655Scognet	uma_set_align(arm_dcache_align_mask);
1208166655Scognet	return (0);
1209129198Scognet}
1210129198Scognet
1211129198Scognet/*
1212129198Scognet * Fixup routines for data and prefetch aborts.
1213129198Scognet *
1214129198Scognet * Several compile time symbols are used
1215129198Scognet *
1216129198Scognet * DEBUG_FAULT_CORRECTION - Print debugging information during the
1217129198Scognet * correction of registers after a fault.
1218129198Scognet */
1219129198Scognet
1220129198Scognet
1221129198Scognet/*
1222129198Scognet * Null abort fixup routine.
1223129198Scognet * For use when no fixup is required.
1224129198Scognet */
1225129198Scognetint
1226129198Scognetcpufunc_null_fixup(arg)
1227129198Scognet	void *arg;
1228129198Scognet{
1229129198Scognet	return(ABORT_FIXUP_OK);
1230129198Scognet}
1231129198Scognet
1232129198Scognet/*
1233129198Scognet * CPU Setup code
1234129198Scognet */
1235129198Scognet
1236266311Sian#if defined (CPU_ARM9) || \
1237172738Simp  defined(CPU_ARM9E) || \
1238161592Scognet  defined(CPU_XSCALE_80200) || defined(CPU_XSCALE_80321) ||		\
1239161592Scognet  defined(CPU_XSCALE_PXA2X0) || defined(CPU_XSCALE_IXP425) ||		\
1240172738Simp  defined(CPU_XSCALE_80219) || defined(CPU_XSCALE_81342) || \
1241244480Sgonzo  defined(CPU_ARM10) ||  defined(CPU_ARM1136) || defined(CPU_ARM1176) ||\
1242207611Skevlo  defined(CPU_FA526) || defined(CPU_FA626TE)
1243129198Scognet
1244129198Scognet#define IGN	0
1245129198Scognet#define OR	1
1246129198Scognet#define BIC	2
1247129198Scognet
1248129198Scognetstruct cpu_option {
1249129198Scognet	char	*co_name;
1250129198Scognet	int	co_falseop;
1251129198Scognet	int	co_trueop;
1252129198Scognet	int	co_value;
1253129198Scognet};
1254129198Scognet
1255137498Strhodesstatic u_int parse_cpu_options(char *, struct cpu_option *, u_int);
1256129198Scognet
1257129198Scognetstatic u_int
1258129198Scognetparse_cpu_options(args, optlist, cpuctrl)
1259129198Scognet	char *args;
1260236991Simp	struct cpu_option *optlist;
1261236991Simp	u_int cpuctrl;
1262129198Scognet{
1263129198Scognet	int integer;
1264129198Scognet
1265129198Scognet	if (args == NULL)
1266129198Scognet		return(cpuctrl);
1267129198Scognet
1268129198Scognet	while (optlist->co_name) {
1269129198Scognet		if (get_bootconf_option(args, optlist->co_name,
1270129198Scognet		    BOOTOPT_TYPE_BOOLEAN, &integer)) {
1271129198Scognet			if (integer) {
1272129198Scognet				if (optlist->co_trueop == OR)
1273129198Scognet					cpuctrl |= optlist->co_value;
1274129198Scognet				else if (optlist->co_trueop == BIC)
1275129198Scognet					cpuctrl &= ~optlist->co_value;
1276129198Scognet			} else {
1277129198Scognet				if (optlist->co_falseop == OR)
1278129198Scognet					cpuctrl |= optlist->co_value;
1279129198Scognet				else if (optlist->co_falseop == BIC)
1280129198Scognet					cpuctrl &= ~optlist->co_value;
1281129198Scognet			}
1282129198Scognet		}
1283129198Scognet		++optlist;
1284129198Scognet	}
1285129198Scognet	return(cpuctrl);
1286129198Scognet}
1287266311Sian#endif /* CPU_ARM9 || XSCALE*/
1288129198Scognet
1289129198Scognet#ifdef CPU_ARM9
1290129198Scognetstruct cpu_option arm9_options[] = {
1291129198Scognet	{ "cpu.cache",		BIC, OR,  (CPU_CONTROL_IC_ENABLE | CPU_CONTROL_DC_ENABLE) },
1292129198Scognet	{ "cpu.nocache",	OR,  BIC, (CPU_CONTROL_IC_ENABLE | CPU_CONTROL_DC_ENABLE) },
1293129198Scognet	{ "arm9.cache",	BIC, OR,  (CPU_CONTROL_IC_ENABLE | CPU_CONTROL_DC_ENABLE) },
1294129198Scognet	{ "arm9.icache",	BIC, OR,  CPU_CONTROL_IC_ENABLE },
1295129198Scognet	{ "arm9.dcache",	BIC, OR,  CPU_CONTROL_DC_ENABLE },
1296129198Scognet	{ "cpu.writebuf",	BIC, OR,  CPU_CONTROL_WBUF_ENABLE },
1297129198Scognet	{ "cpu.nowritebuf",	OR,  BIC, CPU_CONTROL_WBUF_ENABLE },
1298129198Scognet	{ "arm9.writebuf",	BIC, OR,  CPU_CONTROL_WBUF_ENABLE },
1299129198Scognet	{ NULL,			IGN, IGN, 0 }
1300129198Scognet};
1301129198Scognet
1302129198Scognetvoid
1303129198Scognetarm9_setup(args)
1304129198Scognet	char *args;
1305129198Scognet{
1306129198Scognet	int cpuctrl, cpuctrlmask;
1307129198Scognet
1308129198Scognet	cpuctrl = CPU_CONTROL_MMU_ENABLE | CPU_CONTROL_32BP_ENABLE
1309129198Scognet	    | CPU_CONTROL_32BD_ENABLE | CPU_CONTROL_SYST_ENABLE
1310129198Scognet	    | CPU_CONTROL_IC_ENABLE | CPU_CONTROL_DC_ENABLE
1311157618Scognet	    | CPU_CONTROL_WBUF_ENABLE | CPU_CONTROL_LABT_ENABLE |
1312157618Scognet	    CPU_CONTROL_ROUNDROBIN;
1313129198Scognet	cpuctrlmask = CPU_CONTROL_MMU_ENABLE | CPU_CONTROL_32BP_ENABLE
1314129198Scognet		 | CPU_CONTROL_32BD_ENABLE | CPU_CONTROL_SYST_ENABLE
1315129198Scognet		 | CPU_CONTROL_IC_ENABLE | CPU_CONTROL_DC_ENABLE
1316129198Scognet		 | CPU_CONTROL_WBUF_ENABLE | CPU_CONTROL_ROM_ENABLE
1317129198Scognet		 | CPU_CONTROL_BEND_ENABLE | CPU_CONTROL_AFLT_ENABLE
1318146605Scognet		 | CPU_CONTROL_LABT_ENABLE | CPU_CONTROL_VECRELOC
1319146605Scognet		 | CPU_CONTROL_ROUNDROBIN;
1320129198Scognet
1321129198Scognet#ifndef ARM32_DISABLE_ALIGNMENT_FAULTS
1322129198Scognet	cpuctrl |= CPU_CONTROL_AFLT_ENABLE;
1323129198Scognet#endif
1324129198Scognet
1325129198Scognet	cpuctrl = parse_cpu_options(args, arm9_options, cpuctrl);
1326129198Scognet
1327129198Scognet#ifdef __ARMEB__
1328129198Scognet	cpuctrl |= CPU_CONTROL_BEND_ENABLE;
1329129198Scognet#endif
1330142050Scognet	if (vector_page == ARM_VECTORS_HIGH)
1331142050Scognet		cpuctrl |= CPU_CONTROL_VECRELOC;
1332129198Scognet
1333129198Scognet	/* Clear out the cache */
1334129198Scognet	cpu_idcache_wbinv_all();
1335129198Scognet
1336129198Scognet	/* Set the control register */
1337146605Scognet	cpu_control(cpuctrlmask, cpuctrl);
1338129198Scognet	ctrl = cpuctrl;
1339129198Scognet
1340129198Scognet}
1341129198Scognet#endif	/* CPU_ARM9 */
1342129198Scognet
1343172738Simp#if defined(CPU_ARM9E) || defined(CPU_ARM10)
1344129198Scognetstruct cpu_option arm10_options[] = {
1345129198Scognet	{ "cpu.cache",		BIC, OR,  (CPU_CONTROL_IC_ENABLE | CPU_CONTROL_DC_ENABLE) },
1346129198Scognet	{ "cpu.nocache",	OR,  BIC, (CPU_CONTROL_IC_ENABLE | CPU_CONTROL_DC_ENABLE) },
1347129198Scognet	{ "arm10.cache",	BIC, OR,  (CPU_CONTROL_IC_ENABLE | CPU_CONTROL_DC_ENABLE) },
1348129198Scognet	{ "arm10.icache",	BIC, OR,  CPU_CONTROL_IC_ENABLE },
1349129198Scognet	{ "arm10.dcache",	BIC, OR,  CPU_CONTROL_DC_ENABLE },
1350129198Scognet	{ "cpu.writebuf",	BIC, OR,  CPU_CONTROL_WBUF_ENABLE },
1351129198Scognet	{ "cpu.nowritebuf",	OR,  BIC, CPU_CONTROL_WBUF_ENABLE },
1352129198Scognet	{ "arm10.writebuf",	BIC, OR,  CPU_CONTROL_WBUF_ENABLE },
1353129198Scognet	{ NULL,			IGN, IGN, 0 }
1354129198Scognet};
1355129198Scognet
1356129198Scognetvoid
1357129198Scognetarm10_setup(args)
1358129198Scognet	char *args;
1359129198Scognet{
1360129198Scognet	int cpuctrl, cpuctrlmask;
1361129198Scognet
1362129198Scognet	cpuctrl = CPU_CONTROL_MMU_ENABLE | CPU_CONTROL_SYST_ENABLE
1363236991Simp	    | CPU_CONTROL_IC_ENABLE | CPU_CONTROL_DC_ENABLE
1364129198Scognet	    | CPU_CONTROL_WBUF_ENABLE | CPU_CONTROL_BPRD_ENABLE;
1365129198Scognet	cpuctrlmask = CPU_CONTROL_MMU_ENABLE | CPU_CONTROL_SYST_ENABLE
1366129198Scognet	    | CPU_CONTROL_IC_ENABLE | CPU_CONTROL_DC_ENABLE
1367129198Scognet	    | CPU_CONTROL_WBUF_ENABLE | CPU_CONTROL_ROM_ENABLE
1368129198Scognet	    | CPU_CONTROL_BEND_ENABLE | CPU_CONTROL_AFLT_ENABLE
1369129198Scognet	    | CPU_CONTROL_BPRD_ENABLE
1370129198Scognet	    | CPU_CONTROL_ROUNDROBIN | CPU_CONTROL_CPCLK;
1371129198Scognet
1372129198Scognet#ifndef ARM32_DISABLE_ALIGNMENT_FAULTS
1373129198Scognet	cpuctrl |= CPU_CONTROL_AFLT_ENABLE;
1374129198Scognet#endif
1375129198Scognet
1376129198Scognet	cpuctrl = parse_cpu_options(args, arm10_options, cpuctrl);
1377129198Scognet
1378129198Scognet#ifdef __ARMEB__
1379129198Scognet	cpuctrl |= CPU_CONTROL_BEND_ENABLE;
1380129198Scognet#endif
1381129198Scognet
1382129198Scognet	/* Clear out the cache */
1383129198Scognet	cpu_idcache_wbinv_all();
1384129198Scognet
1385129198Scognet	/* Now really make sure they are clean.  */
1386172738Simp	__asm __volatile ("mcr\tp15, 0, r0, c7, c7, 0" : : );
1387129198Scognet
1388174058Scognet	if (vector_page == ARM_VECTORS_HIGH)
1389174058Scognet		cpuctrl |= CPU_CONTROL_VECRELOC;
1390174058Scognet
1391129198Scognet	/* Set the control register */
1392129198Scognet	ctrl = cpuctrl;
1393129198Scognet	cpu_control(0xffffffff, cpuctrl);
1394129198Scognet
1395129198Scognet	/* And again. */
1396129198Scognet	cpu_idcache_wbinv_all();
1397129198Scognet}
1398172738Simp#endif	/* CPU_ARM9E || CPU_ARM10 */
1399129198Scognet
1400244480Sgonzo#if defined(CPU_ARM1136) || defined(CPU_ARM1176)
1401172738Simpstruct cpu_option arm11_options[] = {
1402172738Simp	{ "cpu.cache",		BIC, OR,  (CPU_CONTROL_IC_ENABLE | CPU_CONTROL_DC_ENABLE) },
1403172738Simp	{ "cpu.nocache",	OR,  BIC, (CPU_CONTROL_IC_ENABLE | CPU_CONTROL_DC_ENABLE) },
1404172738Simp	{ "arm11.cache",	BIC, OR,  (CPU_CONTROL_IC_ENABLE | CPU_CONTROL_DC_ENABLE) },
1405172738Simp	{ "arm11.icache",	BIC, OR,  CPU_CONTROL_IC_ENABLE },
1406172738Simp	{ "arm11.dcache",	BIC, OR,  CPU_CONTROL_DC_ENABLE },
1407172738Simp	{ NULL,			IGN, IGN, 0 }
1408172738Simp};
1409172738Simp
1410172738Simpvoid
1411244480Sgonzoarm11x6_setup(char *args)
1412172738Simp{
1413244480Sgonzo	int cpuctrl, cpuctrl_wax;
1414244480Sgonzo	uint32_t auxctrl, auxctrl_wax;
1415244480Sgonzo	uint32_t tmp, tmp2;
1416244480Sgonzo	uint32_t sbz=0;
1417244480Sgonzo	uint32_t cpuid;
1418172738Simp
1419244480Sgonzo	cpuid = cpufunc_id();
1420244480Sgonzo
1421244480Sgonzo	cpuctrl =
1422244480Sgonzo		CPU_CONTROL_MMU_ENABLE  |
1423244480Sgonzo		CPU_CONTROL_DC_ENABLE   |
1424244480Sgonzo		CPU_CONTROL_WBUF_ENABLE |
1425244480Sgonzo		CPU_CONTROL_32BP_ENABLE |
1426244480Sgonzo		CPU_CONTROL_32BD_ENABLE |
1427244480Sgonzo		CPU_CONTROL_LABT_ENABLE |
1428244480Sgonzo		CPU_CONTROL_SYST_ENABLE |
1429244480Sgonzo		CPU_CONTROL_IC_ENABLE;
1430244480Sgonzo
1431244480Sgonzo	/*
1432244480Sgonzo	 * "write as existing" bits
1433244480Sgonzo	 * inverse of this is mask
1434244480Sgonzo	 */
1435244480Sgonzo	cpuctrl_wax =
1436244480Sgonzo		(3 << 30) | /* SBZ */
1437244480Sgonzo		(1 << 29) | /* FA */
1438244480Sgonzo		(1 << 28) | /* TR */
1439244480Sgonzo		(3 << 26) | /* SBZ */
1440244480Sgonzo		(3 << 19) | /* SBZ */
1441244480Sgonzo		(1 << 17);  /* SBZ */
1442244480Sgonzo
1443244480Sgonzo	cpuctrl |= CPU_CONTROL_BPRD_ENABLE;
1444244480Sgonzo	cpuctrl |= CPU_CONTROL_V6_EXTPAGE;
1445244480Sgonzo
1446172738Simp	cpuctrl = parse_cpu_options(args, arm11_options, cpuctrl);
1447244480Sgonzo
1448172738Simp#ifdef __ARMEB__
1449172738Simp	cpuctrl |= CPU_CONTROL_BEND_ENABLE;
1450172738Simp#endif
1451244480Sgonzo
1452239701Sgonzo	if (vector_page == ARM_VECTORS_HIGH)
1453239701Sgonzo		cpuctrl |= CPU_CONTROL_VECRELOC;
1454172738Simp
1455244480Sgonzo	auxctrl = 0;
1456244480Sgonzo	auxctrl_wax = ~0;
1457244480Sgonzo	/*
1458244480Sgonzo	 * This options enables the workaround for the 364296 ARM1136
1459244480Sgonzo	 * r0pX errata (possible cache data corruption with
1460244480Sgonzo	 * hit-under-miss enabled). It sets the undocumented bit 31 in
1461244480Sgonzo	 * the auxiliary control register and the FI bit in the control
1462244480Sgonzo	 * register, thus disabling hit-under-miss without putting the
1463244480Sgonzo	 * processor into full low interrupt latency mode. ARM11MPCore
1464244480Sgonzo	 * is not affected.
1465244480Sgonzo	 */
1466244480Sgonzo	if ((cpuid & CPU_ID_CPU_MASK) == CPU_ID_ARM1136JS) { /* ARM1136JSr0pX */
1467244480Sgonzo		cpuctrl |= CPU_CONTROL_FI_ENABLE;
1468244480Sgonzo		auxctrl = ARM1136_AUXCTL_PFI;
1469244480Sgonzo		auxctrl_wax = ~ARM1136_AUXCTL_PFI;
1470244480Sgonzo	}
1471244480Sgonzo
1472244480Sgonzo	/*
1473244480Sgonzo	 * Enable an errata workaround
1474244480Sgonzo	 */
1475244480Sgonzo	if ((cpuid & CPU_ID_CPU_MASK) == CPU_ID_ARM1176JZS) { /* ARM1176JZSr0 */
1476244480Sgonzo		auxctrl = ARM1176_AUXCTL_PHD;
1477244480Sgonzo		auxctrl_wax = ~ARM1176_AUXCTL_PHD;
1478244480Sgonzo	}
1479244480Sgonzo
1480244480Sgonzo	/* Clear out the cache */
1481172738Simp	cpu_idcache_wbinv_all();
1482172738Simp
1483244480Sgonzo	/* Now really make sure they are clean.  */
1484244480Sgonzo	__asm volatile ("mcr\tp15, 0, %0, c7, c7, 0" : : "r"(sbz));
1485244480Sgonzo
1486244480Sgonzo	/* Allow detection code to find the VFP if it's fitted.  */
1487244480Sgonzo	__asm volatile ("mcr\tp15, 0, %0, c1, c0, 2" : : "r" (0x0fffffff));
1488244480Sgonzo
1489172738Simp	/* Set the control register */
1490239701Sgonzo	ctrl = cpuctrl;
1491244480Sgonzo	cpu_control(~cpuctrl_wax, cpuctrl);
1492172738Simp
1493244480Sgonzo	__asm volatile ("mrc	p15, 0, %0, c1, c0, 1\n\t"
1494244480Sgonzo			"and	%1, %0, %2\n\t"
1495244480Sgonzo			"orr	%1, %1, %3\n\t"
1496244480Sgonzo			"teq	%0, %1\n\t"
1497244480Sgonzo			"mcrne	p15, 0, %1, c1, c0, 1\n\t"
1498244480Sgonzo			: "=r"(tmp), "=r"(tmp2) :
1499244480Sgonzo			  "r"(auxctrl_wax), "r"(auxctrl));
1500244480Sgonzo
1501244480Sgonzo	/* And again. */
1502172738Simp	cpu_idcache_wbinv_all();
1503172738Simp}
1504244480Sgonzo#endif  /* CPU_ARM1136 || CPU_ARM1176 */
1505172738Simp
1506239268Sgonzo#ifdef CPU_MV_PJ4B
1507239268Sgonzovoid
1508239268Sgonzopj4bv7_setup(args)
1509239268Sgonzo	char *args;
1510239268Sgonzo{
1511239268Sgonzo	int cpuctrl;
1512239268Sgonzo
1513239268Sgonzo	pj4b_config();
1514239268Sgonzo
1515239268Sgonzo	cpuctrl = CPU_CONTROL_MMU_ENABLE;
1516239268Sgonzo#ifndef ARM32_DISABLE_ALIGNMENT_FAULTS
1517239268Sgonzo	cpuctrl |= CPU_CONTROL_AFLT_ENABLE;
1518239268Sgonzo#endif
1519239268Sgonzo	cpuctrl |= CPU_CONTROL_DC_ENABLE;
1520239268Sgonzo	cpuctrl |= (0xf << 3);
1521239268Sgonzo	cpuctrl |= CPU_CONTROL_BPRD_ENABLE;
1522239268Sgonzo	cpuctrl |= CPU_CONTROL_IC_ENABLE;
1523239268Sgonzo	if (vector_page == ARM_VECTORS_HIGH)
1524239268Sgonzo		cpuctrl |= CPU_CONTROL_VECRELOC;
1525239268Sgonzo	cpuctrl |= (0x5 << 16) | (1 < 22);
1526239268Sgonzo	cpuctrl |= CPU_CONTROL_V6_EXTPAGE;
1527239268Sgonzo
1528239268Sgonzo	/* Clear out the cache */
1529239268Sgonzo	cpu_idcache_wbinv_all();
1530239268Sgonzo
1531239268Sgonzo	/* Set the control register */
1532239268Sgonzo	ctrl = cpuctrl;
1533239268Sgonzo	cpu_control(0xFFFFFFFF, cpuctrl);
1534239268Sgonzo
1535239268Sgonzo	/* And again. */
1536239268Sgonzo	cpu_idcache_wbinv_all();
1537239268Sgonzo}
1538239268Sgonzo#endif /* CPU_MV_PJ4B */
1539239268Sgonzo
1540266058Sian#if defined(CPU_CORTEXA) || defined(CPU_KRAIT)
1541239268Sgonzo
1542239268Sgonzovoid
1543239268Sgonzocortexa_setup(char *args)
1544239268Sgonzo{
1545239268Sgonzo	int cpuctrl, cpuctrlmask;
1546239268Sgonzo
1547239268Sgonzo	cpuctrlmask = CPU_CONTROL_MMU_ENABLE |     /* MMU enable         [0] */
1548239268Sgonzo	    CPU_CONTROL_AFLT_ENABLE |    /* Alignment fault    [1] */
1549239268Sgonzo	    CPU_CONTROL_DC_ENABLE |      /* DCache enable      [2] */
1550239268Sgonzo	    CPU_CONTROL_BPRD_ENABLE |    /* Branch prediction [11] */
1551239268Sgonzo	    CPU_CONTROL_IC_ENABLE |      /* ICache enable     [12] */
1552239268Sgonzo	    CPU_CONTROL_VECRELOC;        /* Vector relocation [13] */
1553239268Sgonzo
1554239268Sgonzo	cpuctrl = CPU_CONTROL_MMU_ENABLE |
1555239268Sgonzo	    CPU_CONTROL_IC_ENABLE |
1556239268Sgonzo	    CPU_CONTROL_DC_ENABLE |
1557239268Sgonzo	    CPU_CONTROL_BPRD_ENABLE;
1558239268Sgonzo
1559239268Sgonzo#ifndef ARM32_DISABLE_ALIGNMENT_FAULTS
1560239268Sgonzo	cpuctrl |= CPU_CONTROL_AFLT_ENABLE;
1561239268Sgonzo#endif
1562239268Sgonzo
1563239268Sgonzo	/* Switch to big endian */
1564239268Sgonzo#ifdef __ARMEB__
1565239268Sgonzo	cpuctrl |= CPU_CONTROL_BEND_ENABLE;
1566239268Sgonzo#endif
1567239268Sgonzo
1568239268Sgonzo	/* Check if the vector page is at the high address (0xffff0000) */
1569239268Sgonzo	if (vector_page == ARM_VECTORS_HIGH)
1570239268Sgonzo		cpuctrl |= CPU_CONTROL_VECRELOC;
1571239268Sgonzo
1572239268Sgonzo	/* Clear out the cache */
1573239268Sgonzo	cpu_idcache_wbinv_all();
1574239268Sgonzo
1575239268Sgonzo	/* Set the control register */
1576239268Sgonzo	ctrl = cpuctrl;
1577239268Sgonzo	cpu_control(cpuctrlmask, cpuctrl);
1578239268Sgonzo
1579239268Sgonzo	/* And again. */
1580239268Sgonzo	cpu_idcache_wbinv_all();
1581239268Sgonzo#ifdef SMP
1582239268Sgonzo	armv7_auxctrl((1 << 6) | (1 << 0), (1 << 6) | (1 << 0)); /* Enable SMP + TLB broadcasting  */
1583239268Sgonzo#endif
1584239268Sgonzo}
1585239268Sgonzo#endif  /* CPU_CORTEXA */
1586239268Sgonzo
1587207611Skevlo#if defined(CPU_FA526) || defined(CPU_FA626TE)
1588201468Srpaulostruct cpu_option fa526_options[] = {
1589201468Srpaulo#ifdef COMPAT_12
1590201468Srpaulo	{ "nocache",		IGN, BIC, (CPU_CONTROL_IC_ENABLE |
1591201468Srpaulo					   CPU_CONTROL_DC_ENABLE) },
1592201468Srpaulo	{ "nowritebuf",		IGN, BIC, CPU_CONTROL_WBUF_ENABLE },
1593201468Srpaulo#endif	/* COMPAT_12 */
1594201468Srpaulo	{ "cpu.cache",		BIC, OR,  (CPU_CONTROL_IC_ENABLE |
1595201468Srpaulo					   CPU_CONTROL_DC_ENABLE) },
1596201468Srpaulo	{ "cpu.nocache",	OR,  BIC, (CPU_CONTROL_IC_ENABLE |
1597201468Srpaulo					   CPU_CONTROL_DC_ENABLE) },
1598201468Srpaulo	{ "cpu.writebuf",	BIC, OR,  CPU_CONTROL_WBUF_ENABLE },
1599201468Srpaulo	{ "cpu.nowritebuf",	OR,  BIC, CPU_CONTROL_WBUF_ENABLE },
1600201468Srpaulo	{ NULL,			IGN, IGN, 0 }
1601201468Srpaulo};
1602201468Srpaulo
1603201468Srpaulovoid
1604201468Srpaulofa526_setup(char *args)
1605201468Srpaulo{
1606201468Srpaulo	int cpuctrl, cpuctrlmask;
1607201468Srpaulo
1608201468Srpaulo	cpuctrl = CPU_CONTROL_MMU_ENABLE | CPU_CONTROL_32BP_ENABLE
1609201468Srpaulo		 | CPU_CONTROL_32BD_ENABLE | CPU_CONTROL_SYST_ENABLE
1610201468Srpaulo		 | CPU_CONTROL_IC_ENABLE | CPU_CONTROL_DC_ENABLE
1611204122Skevlo		 | CPU_CONTROL_WBUF_ENABLE | CPU_CONTROL_LABT_ENABLE
1612204122Skevlo		| CPU_CONTROL_BPRD_ENABLE;
1613201468Srpaulo	cpuctrlmask = CPU_CONTROL_MMU_ENABLE | CPU_CONTROL_32BP_ENABLE
1614201468Srpaulo		 | CPU_CONTROL_32BD_ENABLE | CPU_CONTROL_SYST_ENABLE
1615201468Srpaulo		 | CPU_CONTROL_IC_ENABLE | CPU_CONTROL_DC_ENABLE
1616201468Srpaulo		 | CPU_CONTROL_WBUF_ENABLE | CPU_CONTROL_ROM_ENABLE
1617201468Srpaulo		 | CPU_CONTROL_BEND_ENABLE | CPU_CONTROL_AFLT_ENABLE
1618201468Srpaulo		 | CPU_CONTROL_LABT_ENABLE | CPU_CONTROL_BPRD_ENABLE
1619201468Srpaulo		 | CPU_CONTROL_CPCLK | CPU_CONTROL_VECRELOC;
1620201468Srpaulo
1621201468Srpaulo#ifndef ARM32_DISABLE_ALIGNMENT_FAULTS
1622201468Srpaulo	cpuctrl |= CPU_CONTROL_AFLT_ENABLE;
1623201468Srpaulo#endif
1624201468Srpaulo
1625201468Srpaulo	cpuctrl = parse_cpu_options(args, fa526_options, cpuctrl);
1626201468Srpaulo
1627201468Srpaulo#ifdef __ARMEB__
1628201468Srpaulo	cpuctrl |= CPU_CONTROL_BEND_ENABLE;
1629201468Srpaulo#endif
1630201468Srpaulo
1631201468Srpaulo	if (vector_page == ARM_VECTORS_HIGH)
1632201468Srpaulo		cpuctrl |= CPU_CONTROL_VECRELOC;
1633201468Srpaulo
1634201468Srpaulo	/* Clear out the cache */
1635201468Srpaulo	cpu_idcache_wbinv_all();
1636201468Srpaulo
1637201468Srpaulo	/* Set the control register */
1638201468Srpaulo	ctrl = cpuctrl;
1639201468Srpaulo	cpu_control(0xffffffff, cpuctrl);
1640201468Srpaulo}
1641207611Skevlo#endif	/* CPU_FA526 || CPU_FA626TE */
1642201468Srpaulo
1643129198Scognet#if defined(CPU_XSCALE_80200) || defined(CPU_XSCALE_80321) || \
1644161592Scognet  defined(CPU_XSCALE_PXA2X0) || defined(CPU_XSCALE_IXP425) || \
1645164080Scognet  defined(CPU_XSCALE_80219) || defined(CPU_XSCALE_81342)
1646129198Scognetstruct cpu_option xscale_options[] = {
1647129198Scognet#ifdef COMPAT_12
1648129198Scognet	{ "branchpredict", 	BIC, OR,  CPU_CONTROL_BPRD_ENABLE },
1649129198Scognet	{ "nocache",		IGN, BIC, (CPU_CONTROL_IC_ENABLE | CPU_CONTROL_DC_ENABLE) },
1650129198Scognet#endif	/* COMPAT_12 */
1651129198Scognet	{ "cpu.branchpredict", 	BIC, OR,  CPU_CONTROL_BPRD_ENABLE },
1652129198Scognet	{ "cpu.cache",		BIC, OR,  (CPU_CONTROL_IC_ENABLE | CPU_CONTROL_DC_ENABLE) },
1653129198Scognet	{ "cpu.nocache",	OR,  BIC, (CPU_CONTROL_IC_ENABLE | CPU_CONTROL_DC_ENABLE) },
1654129198Scognet	{ "xscale.branchpredict", BIC, OR,  CPU_CONTROL_BPRD_ENABLE },
1655129198Scognet	{ "xscale.cache",	BIC, OR,  (CPU_CONTROL_IC_ENABLE | CPU_CONTROL_DC_ENABLE) },
1656129198Scognet	{ "xscale.icache",	BIC, OR,  CPU_CONTROL_IC_ENABLE },
1657129198Scognet	{ "xscale.dcache",	BIC, OR,  CPU_CONTROL_DC_ENABLE },
1658129198Scognet	{ NULL,			IGN, IGN, 0 }
1659129198Scognet};
1660129198Scognet
1661129198Scognetvoid
1662129198Scognetxscale_setup(args)
1663129198Scognet	char *args;
1664129198Scognet{
1665129198Scognet	uint32_t auxctl;
1666129198Scognet	int cpuctrl, cpuctrlmask;
1667129198Scognet
1668129198Scognet	/*
1669129198Scognet	 * The XScale Write Buffer is always enabled.  Our option
1670129198Scognet	 * is to enable/disable coalescing.  Note that bits 6:3
1671129198Scognet	 * must always be enabled.
1672129198Scognet	 */
1673129198Scognet
1674129198Scognet	cpuctrl = CPU_CONTROL_MMU_ENABLE | CPU_CONTROL_32BP_ENABLE
1675129198Scognet		 | CPU_CONTROL_32BD_ENABLE | CPU_CONTROL_SYST_ENABLE
1676129198Scognet		 | CPU_CONTROL_IC_ENABLE | CPU_CONTROL_DC_ENABLE
1677129198Scognet		 | CPU_CONTROL_WBUF_ENABLE | CPU_CONTROL_LABT_ENABLE
1678129198Scognet		 | CPU_CONTROL_BPRD_ENABLE;
1679129198Scognet	cpuctrlmask = CPU_CONTROL_MMU_ENABLE | CPU_CONTROL_32BP_ENABLE
1680129198Scognet		 | CPU_CONTROL_32BD_ENABLE | CPU_CONTROL_SYST_ENABLE
1681129198Scognet		 | CPU_CONTROL_IC_ENABLE | CPU_CONTROL_DC_ENABLE
1682129198Scognet		 | CPU_CONTROL_WBUF_ENABLE | CPU_CONTROL_ROM_ENABLE
1683129198Scognet		 | CPU_CONTROL_BEND_ENABLE | CPU_CONTROL_AFLT_ENABLE
1684129198Scognet		 | CPU_CONTROL_LABT_ENABLE | CPU_CONTROL_BPRD_ENABLE
1685171618Scognet		 | CPU_CONTROL_CPCLK | CPU_CONTROL_VECRELOC | \
1686171618Scognet		 CPU_CONTROL_L2_ENABLE;
1687129198Scognet
1688129198Scognet#ifndef ARM32_DISABLE_ALIGNMENT_FAULTS
1689129198Scognet	cpuctrl |= CPU_CONTROL_AFLT_ENABLE;
1690129198Scognet#endif
1691129198Scognet
1692129198Scognet	cpuctrl = parse_cpu_options(args, xscale_options, cpuctrl);
1693129198Scognet
1694129198Scognet#ifdef __ARMEB__
1695129198Scognet	cpuctrl |= CPU_CONTROL_BEND_ENABLE;
1696129198Scognet#endif
1697129198Scognet
1698129198Scognet	if (vector_page == ARM_VECTORS_HIGH)
1699129198Scognet		cpuctrl |= CPU_CONTROL_VECRELOC;
1700171618Scognet#ifdef CPU_XSCALE_CORE3
1701171618Scognet	cpuctrl |= CPU_CONTROL_L2_ENABLE;
1702171618Scognet#endif
1703129198Scognet
1704129198Scognet	/* Clear out the cache */
1705129198Scognet	cpu_idcache_wbinv_all();
1706129198Scognet
1707129198Scognet	/*
1708129198Scognet	 * Set the control register.  Note that bits 6:3 must always
1709129198Scognet	 * be set to 1.
1710129198Scognet	 */
1711129198Scognet	ctrl = cpuctrl;
1712129198Scognet/*	cpu_control(cpuctrlmask, cpuctrl);*/
1713129198Scognet	cpu_control(0xffffffff, cpuctrl);
1714129198Scognet
1715129198Scognet	/* Make sure write coalescing is turned on */
1716129198Scognet	__asm __volatile("mrc p15, 0, %0, c1, c0, 1"
1717129198Scognet		: "=r" (auxctl));
1718129198Scognet#ifdef XSCALE_NO_COALESCE_WRITES
1719129198Scognet	auxctl |= XSCALE_AUXCTL_K;
1720129198Scognet#else
1721129198Scognet	auxctl &= ~XSCALE_AUXCTL_K;
1722129198Scognet#endif
1723171618Scognet#ifdef CPU_XSCALE_CORE3
1724171618Scognet	auxctl |= XSCALE_AUXCTL_LLR;
1725171618Scognet	auxctl |= XSCALE_AUXCTL_MD_MASK;
1726171618Scognet#endif
1727129198Scognet	__asm __volatile("mcr p15, 0, %0, c1, c0, 1"
1728129198Scognet		: : "r" (auxctl));
1729129198Scognet}
1730236991Simp#endif	/* CPU_XSCALE_80200 || CPU_XSCALE_80321 || CPU_XSCALE_PXA2X0 || CPU_XSCALE_IXP425
1731161592Scognet	   CPU_XSCALE_80219 */
1732