]> CyberLeo.Net >> Repos - FreeBSD/releng/10.0.git/blob - sys/arm/arm/cpufunc.c
- Copy stable/10 (r259064) to releng/10.0 as part of the
[FreeBSD/releng/10.0.git] / sys / arm / arm / cpufunc.c
1 /*      $NetBSD: cpufunc.c,v 1.65 2003/11/05 12:53:15 scw Exp $ */
2
3 /*-
4  * arm7tdmi support code Copyright (c) 2001 John Fremlin
5  * arm8 support code Copyright (c) 1997 ARM Limited
6  * arm8 support code Copyright (c) 1997 Causality Limited
7  * arm9 support code Copyright (C) 2001 ARM Ltd
8  * Copyright (c) 1997 Mark Brinicombe.
9  * Copyright (c) 1997 Causality Limited
10  * All rights reserved.
11  *
12  * Redistribution and use in source and binary forms, with or without
13  * modification, are permitted provided that the following conditions
14  * are met:
15  * 1. Redistributions of source code must retain the above copyright
16  *    notice, this list of conditions and the following disclaimer.
17  * 2. Redistributions in binary form must reproduce the above copyright
18  *    notice, this list of conditions and the following disclaimer in the
19  *    documentation and/or other materials provided with the distribution.
20  * 3. All advertising materials mentioning features or use of this software
21  *    must display the following acknowledgement:
22  *      This product includes software developed by Causality Limited.
23  * 4. The name of Causality Limited may not be used to endorse or promote
24  *    products derived from this software without specific prior written
25  *    permission.
26  *
27  * THIS SOFTWARE IS PROVIDED BY CAUSALITY LIMITED ``AS IS'' AND ANY EXPRESS
28  * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
29  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
30  * DISCLAIMED. IN NO EVENT SHALL CAUSALITY LIMITED BE LIABLE FOR ANY DIRECT,
31  * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
32  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
33  * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
34  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
35  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
36  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
37  * SUCH DAMAGE.
38  *
39  * RiscBSD kernel project
40  *
41  * cpufuncs.c
42  *
43  * C functions for supporting CPU / MMU / TLB specific operations.
44  *
45  * Created      : 30/01/97
46  */
47 #include <sys/cdefs.h>
48 __FBSDID("$FreeBSD$");
49
50 #include <sys/param.h>
51 #include <sys/systm.h>
52 #include <sys/lock.h>
53 #include <sys/mutex.h>
54 #include <sys/bus.h>
55 #include <machine/bus.h>
56 #include <machine/cpu.h>
57 #include <machine/disassem.h>
58
59 #include <vm/vm.h>
60 #include <vm/pmap.h>
61 #include <vm/uma.h>
62
63 #include <machine/cpuconf.h>
64 #include <machine/cpufunc.h>
65 #include <machine/bootconfig.h>
66
67 #ifdef CPU_XSCALE_80200
68 #include <arm/xscale/i80200/i80200reg.h>
69 #include <arm/xscale/i80200/i80200var.h>
70 #endif
71
72 #if defined(CPU_XSCALE_80321) || defined(CPU_XSCALE_80219)
73 #include <arm/xscale/i80321/i80321reg.h>
74 #include <arm/xscale/i80321/i80321var.h>
75 #endif
76
77 /*
78  * Some definitions in i81342reg.h clash with i80321reg.h.
79  * This only happens for the LINT kernel. As it happens,
80  * we don't need anything from i81342reg.h that we already
81  * got from somewhere else during a LINT compile.
82  */
83 #if defined(CPU_XSCALE_81342) && !defined(COMPILING_LINT)
84 #include <arm/xscale/i8134x/i81342reg.h>
85 #endif
86
87 #ifdef CPU_XSCALE_IXP425
88 #include <arm/xscale/ixp425/ixp425reg.h>
89 #include <arm/xscale/ixp425/ixp425var.h>
90 #endif
91
92 /* PRIMARY CACHE VARIABLES */
93 int     arm_picache_size;
94 int     arm_picache_line_size;
95 int     arm_picache_ways;
96
97 int     arm_pdcache_size;       /* and unified */
98 int     arm_pdcache_line_size;
99 int     arm_pdcache_ways;
100
101 int     arm_pcache_type;
102 int     arm_pcache_unified;
103
104 int     arm_dcache_align;
105 int     arm_dcache_align_mask;
106
107 u_int   arm_cache_level;
108 u_int   arm_cache_type[14];
109 u_int   arm_cache_loc;
110
111 /* 1 == use cpu_sleep(), 0 == don't */
112 int cpu_do_powersave;
113 int ctrl;
114
115 #ifdef CPU_ARM7TDMI
116 struct cpu_functions arm7tdmi_cpufuncs = {
117         /* CPU functions */
118         
119         cpufunc_id,                     /* id                   */
120         cpufunc_nullop,                 /* cpwait               */
121
122         /* MMU functions */
123
124         cpufunc_control,                /* control              */
125         cpufunc_domains,                /* domain               */
126         arm7tdmi_setttb,                /* setttb               */
127         cpufunc_faultstatus,            /* faultstatus          */
128         cpufunc_faultaddress,           /* faultaddress         */
129
130         /* TLB functions */
131
132         arm7tdmi_tlb_flushID,           /* tlb_flushID          */
133         arm7tdmi_tlb_flushID_SE,        /* tlb_flushID_SE       */
134         arm7tdmi_tlb_flushID,           /* tlb_flushI           */
135         arm7tdmi_tlb_flushID_SE,        /* tlb_flushI_SE        */
136         arm7tdmi_tlb_flushID,           /* tlb_flushD           */
137         arm7tdmi_tlb_flushID_SE,        /* tlb_flushD_SE        */
138
139         /* Cache operations */
140
141         cpufunc_nullop,                 /* icache_sync_all      */
142         (void *)cpufunc_nullop,         /* icache_sync_range    */
143
144         arm7tdmi_cache_flushID,         /* dcache_wbinv_all     */
145         (void *)arm7tdmi_cache_flushID, /* dcache_wbinv_range   */
146         (void *)arm7tdmi_cache_flushID, /* dcache_inv_range     */
147         (void *)cpufunc_nullop,         /* dcache_wb_range      */
148
149         arm7tdmi_cache_flushID,         /* idcache_wbinv_all    */
150         (void *)arm7tdmi_cache_flushID, /* idcache_wbinv_range  */
151         cpufunc_nullop,                 /* l2cache_wbinv_all    */
152         (void *)cpufunc_nullop,         /* l2cache_wbinv_range  */
153         (void *)cpufunc_nullop,         /* l2cache_inv_range    */
154         (void *)cpufunc_nullop,         /* l2cache_wb_range     */
155
156         /* Other functions */
157
158         cpufunc_nullop,                 /* flush_prefetchbuf    */
159         cpufunc_nullop,                 /* drain_writebuf       */
160         cpufunc_nullop,                 /* flush_brnchtgt_C     */
161         (void *)cpufunc_nullop,         /* flush_brnchtgt_E     */
162
163         (void *)cpufunc_nullop,         /* sleep                */
164
165         /* Soft functions */
166
167         late_abort_fixup,               /* dataabt_fixup        */
168         cpufunc_null_fixup,             /* prefetchabt_fixup    */
169
170         arm7tdmi_context_switch,        /* context_switch       */
171
172         arm7tdmi_setup                  /* cpu setup            */
173
174 };
175 #endif  /* CPU_ARM7TDMI */
176
177 #ifdef CPU_ARM8
178 struct cpu_functions arm8_cpufuncs = {
179         /* CPU functions */
180         
181         cpufunc_id,                     /* id                   */
182         cpufunc_nullop,                 /* cpwait               */
183
184         /* MMU functions */
185
186         cpufunc_control,                /* control              */
187         cpufunc_domains,                /* domain               */
188         arm8_setttb,                    /* setttb               */
189         cpufunc_faultstatus,            /* faultstatus          */
190         cpufunc_faultaddress,           /* faultaddress         */
191
192         /* TLB functions */
193
194         arm8_tlb_flushID,               /* tlb_flushID          */
195         arm8_tlb_flushID_SE,            /* tlb_flushID_SE       */
196         arm8_tlb_flushID,               /* tlb_flushI           */
197         arm8_tlb_flushID_SE,            /* tlb_flushI_SE        */
198         arm8_tlb_flushID,               /* tlb_flushD           */
199         arm8_tlb_flushID_SE,            /* tlb_flushD_SE        */
200
201         /* Cache operations */
202
203         cpufunc_nullop,                 /* icache_sync_all      */
204         (void *)cpufunc_nullop,         /* icache_sync_range    */
205
206         arm8_cache_purgeID,             /* dcache_wbinv_all     */
207         (void *)arm8_cache_purgeID,     /* dcache_wbinv_range   */
208 /*XXX*/ (void *)arm8_cache_purgeID,     /* dcache_inv_range     */
209         (void *)arm8_cache_cleanID,     /* dcache_wb_range      */
210
211         arm8_cache_purgeID,             /* idcache_wbinv_all    */
212         (void *)arm8_cache_purgeID,     /* idcache_wbinv_range  */
213         cpufunc_nullop,                 /* l2cache_wbinv_all    */
214         (void *)cpufunc_nullop,         /* l2cache_wbinv_range  */
215         (void *)cpufunc_nullop,         /* l2cache_inv_range    */
216         (void *)cpufunc_nullop,         /* l2cache_wb_range     */
217
218         /* Other functions */
219
220         cpufunc_nullop,                 /* flush_prefetchbuf    */
221         cpufunc_nullop,                 /* drain_writebuf       */
222         cpufunc_nullop,                 /* flush_brnchtgt_C     */
223         (void *)cpufunc_nullop,         /* flush_brnchtgt_E     */
224
225         (void *)cpufunc_nullop,         /* sleep                */
226
227         /* Soft functions */
228
229         cpufunc_null_fixup,             /* dataabt_fixup        */
230         cpufunc_null_fixup,             /* prefetchabt_fixup    */
231
232         arm8_context_switch,            /* context_switch       */
233
234         arm8_setup                      /* cpu setup            */
235 };
236 #endif  /* CPU_ARM8 */
237
238 #ifdef CPU_ARM9
239 struct cpu_functions arm9_cpufuncs = {
240         /* CPU functions */
241
242         cpufunc_id,                     /* id                   */
243         cpufunc_nullop,                 /* cpwait               */
244
245         /* MMU functions */
246
247         cpufunc_control,                /* control              */
248         cpufunc_domains,                /* Domain               */
249         arm9_setttb,                    /* Setttb               */
250         cpufunc_faultstatus,            /* Faultstatus          */
251         cpufunc_faultaddress,           /* Faultaddress         */
252
253         /* TLB functions */
254
255         armv4_tlb_flushID,              /* tlb_flushID          */
256         arm9_tlb_flushID_SE,            /* tlb_flushID_SE       */
257         armv4_tlb_flushI,               /* tlb_flushI           */
258         (void *)armv4_tlb_flushI,       /* tlb_flushI_SE        */
259         armv4_tlb_flushD,               /* tlb_flushD           */
260         armv4_tlb_flushD_SE,            /* tlb_flushD_SE        */
261
262         /* Cache operations */
263
264         arm9_icache_sync_all,           /* icache_sync_all      */
265         arm9_icache_sync_range,         /* icache_sync_range    */
266
267         arm9_dcache_wbinv_all,          /* dcache_wbinv_all     */
268         arm9_dcache_wbinv_range,        /* dcache_wbinv_range   */
269         arm9_dcache_inv_range,          /* dcache_inv_range     */
270         arm9_dcache_wb_range,           /* dcache_wb_range      */
271
272         arm9_idcache_wbinv_all,         /* idcache_wbinv_all    */
273         arm9_idcache_wbinv_range,       /* idcache_wbinv_range  */
274         cpufunc_nullop,                 /* l2cache_wbinv_all    */
275         (void *)cpufunc_nullop,         /* l2cache_wbinv_range  */
276         (void *)cpufunc_nullop,         /* l2cache_inv_range    */
277         (void *)cpufunc_nullop,         /* l2cache_wb_range     */
278
279         /* Other functions */
280
281         cpufunc_nullop,                 /* flush_prefetchbuf    */
282         armv4_drain_writebuf,           /* drain_writebuf       */
283         cpufunc_nullop,                 /* flush_brnchtgt_C     */
284         (void *)cpufunc_nullop,         /* flush_brnchtgt_E     */
285
286         (void *)cpufunc_nullop,         /* sleep                */
287
288         /* Soft functions */
289
290         cpufunc_null_fixup,             /* dataabt_fixup        */
291         cpufunc_null_fixup,             /* prefetchabt_fixup    */
292
293         arm9_context_switch,            /* context_switch       */
294
295         arm9_setup                      /* cpu setup            */
296
297 };
298 #endif /* CPU_ARM9 */
299
300 #if defined(CPU_ARM9E) || defined(CPU_ARM10)
301 struct cpu_functions armv5_ec_cpufuncs = {
302         /* CPU functions */
303
304         cpufunc_id,                     /* id                   */
305         cpufunc_nullop,                 /* cpwait               */
306
307         /* MMU functions */
308
309         cpufunc_control,                /* control              */
310         cpufunc_domains,                /* Domain               */
311         armv5_ec_setttb,                /* Setttb               */
312         cpufunc_faultstatus,            /* Faultstatus          */
313         cpufunc_faultaddress,           /* Faultaddress         */
314
315         /* TLB functions */
316
317         armv4_tlb_flushID,              /* tlb_flushID          */
318         arm10_tlb_flushID_SE,           /* tlb_flushID_SE       */
319         armv4_tlb_flushI,               /* tlb_flushI           */
320         arm10_tlb_flushI_SE,            /* tlb_flushI_SE        */
321         armv4_tlb_flushD,               /* tlb_flushD           */
322         armv4_tlb_flushD_SE,            /* tlb_flushD_SE        */
323
324         /* Cache operations */
325
326         armv5_ec_icache_sync_all,       /* icache_sync_all      */
327         armv5_ec_icache_sync_range,     /* icache_sync_range    */
328
329         armv5_ec_dcache_wbinv_all,      /* dcache_wbinv_all     */
330         armv5_ec_dcache_wbinv_range,    /* dcache_wbinv_range   */
331         armv5_ec_dcache_inv_range,      /* dcache_inv_range     */
332         armv5_ec_dcache_wb_range,       /* dcache_wb_range      */
333
334         armv5_ec_idcache_wbinv_all,     /* idcache_wbinv_all    */
335         armv5_ec_idcache_wbinv_range,   /* idcache_wbinv_range  */
336
337         cpufunc_nullop,                 /* l2cache_wbinv_all    */
338         (void *)cpufunc_nullop,         /* l2cache_wbinv_range  */
339         (void *)cpufunc_nullop,         /* l2cache_inv_range    */
340         (void *)cpufunc_nullop,         /* l2cache_wb_range     */
341
342         /* Other functions */
343
344         cpufunc_nullop,                 /* flush_prefetchbuf    */
345         armv4_drain_writebuf,           /* drain_writebuf       */
346         cpufunc_nullop,                 /* flush_brnchtgt_C     */
347         (void *)cpufunc_nullop,         /* flush_brnchtgt_E     */
348
349         (void *)cpufunc_nullop,         /* sleep                */
350
351         /* Soft functions */
352
353         cpufunc_null_fixup,             /* dataabt_fixup        */
354         cpufunc_null_fixup,             /* prefetchabt_fixup    */
355
356         arm10_context_switch,           /* context_switch       */
357
358         arm10_setup                     /* cpu setup            */
359
360 };
361
362 struct cpu_functions sheeva_cpufuncs = {
363         /* CPU functions */
364
365         cpufunc_id,                     /* id                   */
366         cpufunc_nullop,                 /* cpwait               */
367
368         /* MMU functions */
369
370         cpufunc_control,                /* control              */
371         cpufunc_domains,                /* Domain               */
372         sheeva_setttb,                  /* Setttb               */
373         cpufunc_faultstatus,            /* Faultstatus          */
374         cpufunc_faultaddress,           /* Faultaddress         */
375
376         /* TLB functions */
377
378         armv4_tlb_flushID,              /* tlb_flushID          */
379         arm10_tlb_flushID_SE,           /* tlb_flushID_SE       */
380         armv4_tlb_flushI,               /* tlb_flushI           */
381         arm10_tlb_flushI_SE,            /* tlb_flushI_SE        */
382         armv4_tlb_flushD,               /* tlb_flushD           */
383         armv4_tlb_flushD_SE,            /* tlb_flushD_SE        */
384
385         /* Cache operations */
386
387         armv5_ec_icache_sync_all,       /* icache_sync_all      */
388         armv5_ec_icache_sync_range,     /* icache_sync_range    */
389
390         armv5_ec_dcache_wbinv_all,      /* dcache_wbinv_all     */
391         sheeva_dcache_wbinv_range,      /* dcache_wbinv_range   */
392         sheeva_dcache_inv_range,        /* dcache_inv_range     */
393         sheeva_dcache_wb_range,         /* dcache_wb_range      */
394
395         armv5_ec_idcache_wbinv_all,     /* idcache_wbinv_all    */
396         sheeva_idcache_wbinv_range,     /* idcache_wbinv_all    */
397
398         sheeva_l2cache_wbinv_all,       /* l2cache_wbinv_all    */
399         sheeva_l2cache_wbinv_range,     /* l2cache_wbinv_range  */
400         sheeva_l2cache_inv_range,       /* l2cache_inv_range    */
401         sheeva_l2cache_wb_range,        /* l2cache_wb_range     */
402
403         /* Other functions */
404
405         cpufunc_nullop,                 /* flush_prefetchbuf    */
406         armv4_drain_writebuf,           /* drain_writebuf       */
407         cpufunc_nullop,                 /* flush_brnchtgt_C     */
408         (void *)cpufunc_nullop,         /* flush_brnchtgt_E     */
409
410         sheeva_cpu_sleep,               /* sleep                */
411
412         /* Soft functions */
413
414         cpufunc_null_fixup,             /* dataabt_fixup        */
415         cpufunc_null_fixup,             /* prefetchabt_fixup    */
416
417         arm10_context_switch,           /* context_switch       */
418
419         arm10_setup                     /* cpu setup            */
420 };
421 #endif /* CPU_ARM9E || CPU_ARM10 */
422
423 #ifdef CPU_ARM10
424 struct cpu_functions arm10_cpufuncs = {
425         /* CPU functions */
426
427         cpufunc_id,                     /* id                   */
428         cpufunc_nullop,                 /* cpwait               */
429
430         /* MMU functions */
431
432         cpufunc_control,                /* control              */
433         cpufunc_domains,                /* Domain               */
434         arm10_setttb,                   /* Setttb               */
435         cpufunc_faultstatus,            /* Faultstatus          */
436         cpufunc_faultaddress,           /* Faultaddress         */
437
438         /* TLB functions */
439
440         armv4_tlb_flushID,              /* tlb_flushID          */
441         arm10_tlb_flushID_SE,           /* tlb_flushID_SE       */
442         armv4_tlb_flushI,               /* tlb_flushI           */
443         arm10_tlb_flushI_SE,            /* tlb_flushI_SE        */
444         armv4_tlb_flushD,               /* tlb_flushD           */
445         armv4_tlb_flushD_SE,            /* tlb_flushD_SE        */
446
447         /* Cache operations */
448
449         arm10_icache_sync_all,          /* icache_sync_all      */
450         arm10_icache_sync_range,        /* icache_sync_range    */
451
452         arm10_dcache_wbinv_all,         /* dcache_wbinv_all     */
453         arm10_dcache_wbinv_range,       /* dcache_wbinv_range   */
454         arm10_dcache_inv_range,         /* dcache_inv_range     */
455         arm10_dcache_wb_range,          /* dcache_wb_range      */
456
457         arm10_idcache_wbinv_all,        /* idcache_wbinv_all    */
458         arm10_idcache_wbinv_range,      /* idcache_wbinv_range  */
459         cpufunc_nullop,                 /* l2cache_wbinv_all    */
460         (void *)cpufunc_nullop,         /* l2cache_wbinv_range  */
461         (void *)cpufunc_nullop,         /* l2cache_inv_range    */
462         (void *)cpufunc_nullop,         /* l2cache_wb_range     */
463
464         /* Other functions */
465
466         cpufunc_nullop,                 /* flush_prefetchbuf    */
467         armv4_drain_writebuf,           /* drain_writebuf       */
468         cpufunc_nullop,                 /* flush_brnchtgt_C     */
469         (void *)cpufunc_nullop,         /* flush_brnchtgt_E     */
470
471         (void *)cpufunc_nullop,         /* sleep                */
472
473         /* Soft functions */
474
475         cpufunc_null_fixup,             /* dataabt_fixup        */
476         cpufunc_null_fixup,             /* prefetchabt_fixup    */
477
478         arm10_context_switch,           /* context_switch       */
479
480         arm10_setup                     /* cpu setup            */
481
482 };
483 #endif /* CPU_ARM10 */
484
485 #ifdef CPU_MV_PJ4B
486 struct cpu_functions pj4bv7_cpufuncs = {
487         /* CPU functions */
488
489         cpufunc_id,                     /* id                   */
490         arm11_drain_writebuf,           /* cpwait               */
491
492         /* MMU functions */
493
494         cpufunc_control,                /* control              */
495         cpufunc_domains,                /* Domain               */
496         pj4b_setttb,                    /* Setttb               */
497         cpufunc_faultstatus,            /* Faultstatus          */
498         cpufunc_faultaddress,           /* Faultaddress         */
499
500         /* TLB functions */
501
502         armv7_tlb_flushID,              /* tlb_flushID          */
503         armv7_tlb_flushID_SE,           /* tlb_flushID_SE       */
504         armv7_tlb_flushID,              /* tlb_flushI           */
505         armv7_tlb_flushID_SE,           /* tlb_flushI_SE        */
506         armv7_tlb_flushID,              /* tlb_flushD           */
507         armv7_tlb_flushID_SE,           /* tlb_flushD_SE        */
508
509         /* Cache operations */
510         armv7_idcache_wbinv_all,        /* icache_sync_all      */
511         armv7_icache_sync_range,        /* icache_sync_range    */
512
513         armv7_dcache_wbinv_all,         /* dcache_wbinv_all     */
514         armv7_dcache_wbinv_range,       /* dcache_wbinv_range   */
515         armv7_dcache_inv_range,         /* dcache_inv_range     */
516         armv7_dcache_wb_range,          /* dcache_wb_range      */
517
518         armv7_idcache_wbinv_all,        /* idcache_wbinv_all    */
519         armv7_idcache_wbinv_range,      /* idcache_wbinv_all    */
520
521         (void *)cpufunc_nullop,         /* l2cache_wbinv_all    */
522         (void *)cpufunc_nullop,         /* l2cache_wbinv_range  */
523         (void *)cpufunc_nullop,         /* l2cache_inv_range    */
524         (void *)cpufunc_nullop,         /* l2cache_wb_range     */
525
526         /* Other functions */
527
528         pj4b_drain_readbuf,             /* flush_prefetchbuf    */
529         arm11_drain_writebuf,           /* drain_writebuf       */
530         pj4b_flush_brnchtgt_all,        /* flush_brnchtgt_C     */
531         pj4b_flush_brnchtgt_va,         /* flush_brnchtgt_E     */
532
533         (void *)cpufunc_nullop,         /* sleep                */
534
535         /* Soft functions */
536
537         cpufunc_null_fixup,             /* dataabt_fixup        */
538         cpufunc_null_fixup,             /* prefetchabt_fixup    */
539
540         arm11_context_switch,           /* context_switch       */
541
542         pj4bv7_setup                    /* cpu setup            */
543 };
544
545 struct cpu_functions pj4bv6_cpufuncs = {
546         /* CPU functions */
547
548         cpufunc_id,                     /* id                   */
549         arm11_drain_writebuf,           /* cpwait               */
550
551         /* MMU functions */
552
553         cpufunc_control,                /* control              */
554         cpufunc_domains,                /* Domain               */
555         pj4b_setttb,                    /* Setttb               */
556         cpufunc_faultstatus,            /* Faultstatus          */
557         cpufunc_faultaddress,           /* Faultaddress         */
558
559         /* TLB functions */
560
561         arm11_tlb_flushID,              /* tlb_flushID          */
562         arm11_tlb_flushID_SE,           /* tlb_flushID_SE       */
563         arm11_tlb_flushI,               /* tlb_flushI           */
564         arm11_tlb_flushI_SE,            /* tlb_flushI_SE        */
565         arm11_tlb_flushD,               /* tlb_flushD           */
566         arm11_tlb_flushD_SE,            /* tlb_flushD_SE        */
567
568         /* Cache operations */
569         armv6_icache_sync_all,          /* icache_sync_all      */
570         pj4b_icache_sync_range,         /* icache_sync_range    */
571
572         armv6_dcache_wbinv_all,         /* dcache_wbinv_all     */
573         pj4b_dcache_wbinv_range,        /* dcache_wbinv_range   */
574         pj4b_dcache_inv_range,          /* dcache_inv_range     */
575         pj4b_dcache_wb_range,           /* dcache_wb_range      */
576
577         armv6_idcache_wbinv_all,        /* idcache_wbinv_all    */
578         pj4b_idcache_wbinv_range,       /* idcache_wbinv_all    */
579
580         (void *)cpufunc_nullop,         /* l2cache_wbinv_all    */
581         (void *)cpufunc_nullop,         /* l2cache_wbinv_range  */
582         (void *)cpufunc_nullop,         /* l2cache_inv_range    */
583         (void *)cpufunc_nullop,         /* l2cache_wb_range     */
584
585         /* Other functions */
586
587         pj4b_drain_readbuf,             /* flush_prefetchbuf    */
588         arm11_drain_writebuf,           /* drain_writebuf       */
589         pj4b_flush_brnchtgt_all,        /* flush_brnchtgt_C     */
590         pj4b_flush_brnchtgt_va,         /* flush_brnchtgt_E     */
591
592         (void *)cpufunc_nullop,         /* sleep                */
593
594         /* Soft functions */
595
596         cpufunc_null_fixup,             /* dataabt_fixup        */
597         cpufunc_null_fixup,             /* prefetchabt_fixup    */
598
599         arm11_context_switch,           /* context_switch       */
600
601         pj4bv6_setup                    /* cpu setup            */
602 };
603 #endif /* CPU_MV_PJ4B */
604
605 #ifdef CPU_SA110
606 struct cpu_functions sa110_cpufuncs = {
607         /* CPU functions */
608         
609         cpufunc_id,                     /* id                   */
610         cpufunc_nullop,                 /* cpwait               */
611
612         /* MMU functions */
613
614         cpufunc_control,                /* control              */
615         cpufunc_domains,                /* domain               */
616         sa1_setttb,                     /* setttb               */
617         cpufunc_faultstatus,            /* faultstatus          */
618         cpufunc_faultaddress,           /* faultaddress         */
619
620         /* TLB functions */
621
622         armv4_tlb_flushID,              /* tlb_flushID          */
623         sa1_tlb_flushID_SE,             /* tlb_flushID_SE       */
624         armv4_tlb_flushI,               /* tlb_flushI           */
625         (void *)armv4_tlb_flushI,       /* tlb_flushI_SE        */
626         armv4_tlb_flushD,               /* tlb_flushD           */
627         armv4_tlb_flushD_SE,            /* tlb_flushD_SE        */
628
629         /* Cache operations */
630
631         sa1_cache_syncI,                /* icache_sync_all      */
632         sa1_cache_syncI_rng,            /* icache_sync_range    */
633
634         sa1_cache_purgeD,               /* dcache_wbinv_all     */
635         sa1_cache_purgeD_rng,           /* dcache_wbinv_range   */
636 /*XXX*/ sa1_cache_purgeD_rng,           /* dcache_inv_range     */
637         sa1_cache_cleanD_rng,           /* dcache_wb_range      */
638
639         sa1_cache_purgeID,              /* idcache_wbinv_all    */
640         sa1_cache_purgeID_rng,          /* idcache_wbinv_range  */
641         cpufunc_nullop,                 /* l2cache_wbinv_all    */
642         (void *)cpufunc_nullop,         /* l2cache_wbinv_range  */
643         (void *)cpufunc_nullop,         /* l2cache_inv_range    */
644         (void *)cpufunc_nullop,         /* l2cache_wb_range     */
645
646         /* Other functions */
647
648         cpufunc_nullop,                 /* flush_prefetchbuf    */
649         armv4_drain_writebuf,           /* drain_writebuf       */
650         cpufunc_nullop,                 /* flush_brnchtgt_C     */
651         (void *)cpufunc_nullop,         /* flush_brnchtgt_E     */
652
653         (void *)cpufunc_nullop,         /* sleep                */
654
655         /* Soft functions */
656
657         cpufunc_null_fixup,             /* dataabt_fixup        */
658         cpufunc_null_fixup,             /* prefetchabt_fixup    */
659
660         sa110_context_switch,           /* context_switch       */
661
662         sa110_setup                     /* cpu setup            */
663 };
664 #endif  /* CPU_SA110 */
665
666 #if defined(CPU_SA1100) || defined(CPU_SA1110)
667 struct cpu_functions sa11x0_cpufuncs = {
668         /* CPU functions */
669         
670         cpufunc_id,                     /* id                   */
671         cpufunc_nullop,                 /* cpwait               */
672
673         /* MMU functions */
674
675         cpufunc_control,                /* control              */
676         cpufunc_domains,                /* domain               */
677         sa1_setttb,                     /* setttb               */
678         cpufunc_faultstatus,            /* faultstatus          */
679         cpufunc_faultaddress,           /* faultaddress         */
680
681         /* TLB functions */
682
683         armv4_tlb_flushID,              /* tlb_flushID          */
684         sa1_tlb_flushID_SE,             /* tlb_flushID_SE       */
685         armv4_tlb_flushI,               /* tlb_flushI           */
686         (void *)armv4_tlb_flushI,       /* tlb_flushI_SE        */
687         armv4_tlb_flushD,               /* tlb_flushD           */
688         armv4_tlb_flushD_SE,            /* tlb_flushD_SE        */
689
690         /* Cache operations */
691
692         sa1_cache_syncI,                /* icache_sync_all      */
693         sa1_cache_syncI_rng,            /* icache_sync_range    */
694
695         sa1_cache_purgeD,               /* dcache_wbinv_all     */
696         sa1_cache_purgeD_rng,           /* dcache_wbinv_range   */
697 /*XXX*/ sa1_cache_purgeD_rng,           /* dcache_inv_range     */
698         sa1_cache_cleanD_rng,           /* dcache_wb_range      */
699
700         sa1_cache_purgeID,              /* idcache_wbinv_all    */
701         sa1_cache_purgeID_rng,          /* idcache_wbinv_range  */
702         cpufunc_nullop,                 /* l2cache_wbinv_all    */
703         (void *)cpufunc_nullop,         /* l2cache_wbinv_range  */
704         (void *)cpufunc_nullop,         /* l2cache_inv_range    */
705         (void *)cpufunc_nullop,         /* l2cache_wb_range     */
706
707         /* Other functions */
708
709         sa11x0_drain_readbuf,           /* flush_prefetchbuf    */
710         armv4_drain_writebuf,           /* drain_writebuf       */
711         cpufunc_nullop,                 /* flush_brnchtgt_C     */
712         (void *)cpufunc_nullop,         /* flush_brnchtgt_E     */
713
714         sa11x0_cpu_sleep,               /* sleep                */
715
716         /* Soft functions */
717
718         cpufunc_null_fixup,             /* dataabt_fixup        */
719         cpufunc_null_fixup,             /* prefetchabt_fixup    */
720
721         sa11x0_context_switch,          /* context_switch       */
722
723         sa11x0_setup                    /* cpu setup            */
724 };
725 #endif  /* CPU_SA1100 || CPU_SA1110 */
726
727 #ifdef CPU_IXP12X0
728 struct cpu_functions ixp12x0_cpufuncs = {
729         /* CPU functions */
730         
731         cpufunc_id,                     /* id                   */
732         cpufunc_nullop,                 /* cpwait               */
733
734         /* MMU functions */
735
736         cpufunc_control,                /* control              */
737         cpufunc_domains,                /* domain               */
738         sa1_setttb,                     /* setttb               */
739         cpufunc_faultstatus,            /* faultstatus          */
740         cpufunc_faultaddress,           /* faultaddress         */
741
742         /* TLB functions */
743
744         armv4_tlb_flushID,              /* tlb_flushID          */
745         sa1_tlb_flushID_SE,             /* tlb_flushID_SE       */
746         armv4_tlb_flushI,               /* tlb_flushI           */
747         (void *)armv4_tlb_flushI,       /* tlb_flushI_SE        */
748         armv4_tlb_flushD,               /* tlb_flushD           */
749         armv4_tlb_flushD_SE,            /* tlb_flushD_SE        */
750
751         /* Cache operations */
752
753         sa1_cache_syncI,                /* icache_sync_all      */
754         sa1_cache_syncI_rng,            /* icache_sync_range    */
755
756         sa1_cache_purgeD,               /* dcache_wbinv_all     */
757         sa1_cache_purgeD_rng,           /* dcache_wbinv_range   */
758 /*XXX*/ sa1_cache_purgeD_rng,           /* dcache_inv_range     */
759         sa1_cache_cleanD_rng,           /* dcache_wb_range      */
760
761         sa1_cache_purgeID,              /* idcache_wbinv_all    */
762         sa1_cache_purgeID_rng,          /* idcache_wbinv_range  */
763         cpufunc_nullop,                 /* l2cache_wbinv_all    */
764         (void *)cpufunc_nullop,         /* l2cache_wbinv_range  */
765         (void *)cpufunc_nullop,         /* l2cache_inv_range    */
766         (void *)cpufunc_nullop,         /* l2cache_wb_range     */
767
768         /* Other functions */
769
770         ixp12x0_drain_readbuf,                  /* flush_prefetchbuf    */
771         armv4_drain_writebuf,           /* drain_writebuf       */
772         cpufunc_nullop,                 /* flush_brnchtgt_C     */
773         (void *)cpufunc_nullop,         /* flush_brnchtgt_E     */
774
775         (void *)cpufunc_nullop,         /* sleep                */
776
777         /* Soft functions */
778
779         cpufunc_null_fixup,             /* dataabt_fixup        */
780         cpufunc_null_fixup,             /* prefetchabt_fixup    */
781
782         ixp12x0_context_switch,         /* context_switch       */
783
784         ixp12x0_setup                   /* cpu setup            */
785 };
786 #endif  /* CPU_IXP12X0 */
787
788 #if defined(CPU_XSCALE_80200) || defined(CPU_XSCALE_80321) || \
789   defined(CPU_XSCALE_PXA2X0) || defined(CPU_XSCALE_IXP425) || \
790   defined(CPU_XSCALE_80219)
791
792 struct cpu_functions xscale_cpufuncs = {
793         /* CPU functions */
794         
795         cpufunc_id,                     /* id                   */
796         xscale_cpwait,                  /* cpwait               */
797
798         /* MMU functions */
799
800         xscale_control,                 /* control              */
801         cpufunc_domains,                /* domain               */
802         xscale_setttb,                  /* setttb               */
803         cpufunc_faultstatus,            /* faultstatus          */
804         cpufunc_faultaddress,           /* faultaddress         */
805
806         /* TLB functions */
807
808         armv4_tlb_flushID,              /* tlb_flushID          */
809         xscale_tlb_flushID_SE,          /* tlb_flushID_SE       */
810         armv4_tlb_flushI,               /* tlb_flushI           */
811         (void *)armv4_tlb_flushI,       /* tlb_flushI_SE        */
812         armv4_tlb_flushD,               /* tlb_flushD           */
813         armv4_tlb_flushD_SE,            /* tlb_flushD_SE        */
814
815         /* Cache operations */
816
817         xscale_cache_syncI,             /* icache_sync_all      */
818         xscale_cache_syncI_rng,         /* icache_sync_range    */
819
820         xscale_cache_purgeD,            /* dcache_wbinv_all     */
821         xscale_cache_purgeD_rng,        /* dcache_wbinv_range   */
822         xscale_cache_flushD_rng,        /* dcache_inv_range     */
823         xscale_cache_cleanD_rng,        /* dcache_wb_range      */
824
825         xscale_cache_purgeID,           /* idcache_wbinv_all    */
826         xscale_cache_purgeID_rng,       /* idcache_wbinv_range  */
827         cpufunc_nullop,                 /* l2cache_wbinv_all    */
828         (void *)cpufunc_nullop,         /* l2cache_wbinv_range  */
829         (void *)cpufunc_nullop,         /* l2cache_inv_range    */
830         (void *)cpufunc_nullop,         /* l2cache_wb_range     */
831
832         /* Other functions */
833
834         cpufunc_nullop,                 /* flush_prefetchbuf    */
835         armv4_drain_writebuf,           /* drain_writebuf       */
836         cpufunc_nullop,                 /* flush_brnchtgt_C     */
837         (void *)cpufunc_nullop,         /* flush_brnchtgt_E     */
838
839         xscale_cpu_sleep,               /* sleep                */
840
841         /* Soft functions */
842
843         cpufunc_null_fixup,             /* dataabt_fixup        */
844         cpufunc_null_fixup,             /* prefetchabt_fixup    */
845
846         xscale_context_switch,          /* context_switch       */
847
848         xscale_setup                    /* cpu setup            */
849 };
850 #endif
851 /* CPU_XSCALE_80200 || CPU_XSCALE_80321 || CPU_XSCALE_PXA2X0 || CPU_XSCALE_IXP425
852    CPU_XSCALE_80219 */
853
854 #ifdef CPU_XSCALE_81342
855 struct cpu_functions xscalec3_cpufuncs = {
856         /* CPU functions */
857         
858         cpufunc_id,                     /* id                   */
859         xscale_cpwait,                  /* cpwait               */
860
861         /* MMU functions */
862
863         xscale_control,                 /* control              */
864         cpufunc_domains,                /* domain               */
865         xscalec3_setttb,                /* setttb               */
866         cpufunc_faultstatus,            /* faultstatus          */
867         cpufunc_faultaddress,           /* faultaddress         */
868
869         /* TLB functions */
870
871         armv4_tlb_flushID,              /* tlb_flushID          */
872         xscale_tlb_flushID_SE,          /* tlb_flushID_SE       */
873         armv4_tlb_flushI,               /* tlb_flushI           */
874         (void *)armv4_tlb_flushI,       /* tlb_flushI_SE        */
875         armv4_tlb_flushD,               /* tlb_flushD           */
876         armv4_tlb_flushD_SE,            /* tlb_flushD_SE        */
877
878         /* Cache operations */
879
880         xscalec3_cache_syncI,           /* icache_sync_all      */
881         xscalec3_cache_syncI_rng,       /* icache_sync_range    */
882
883         xscalec3_cache_purgeD,          /* dcache_wbinv_all     */
884         xscalec3_cache_purgeD_rng,      /* dcache_wbinv_range   */
885         xscale_cache_flushD_rng,        /* dcache_inv_range     */
886         xscalec3_cache_cleanD_rng,      /* dcache_wb_range      */
887
888         xscalec3_cache_purgeID,         /* idcache_wbinv_all    */
889         xscalec3_cache_purgeID_rng,     /* idcache_wbinv_range  */
890         xscalec3_l2cache_purge,         /* l2cache_wbinv_all    */
891         xscalec3_l2cache_purge_rng,     /* l2cache_wbinv_range  */
892         xscalec3_l2cache_flush_rng,     /* l2cache_inv_range    */
893         xscalec3_l2cache_clean_rng,     /* l2cache_wb_range     */
894
895         /* Other functions */
896
897         cpufunc_nullop,                 /* flush_prefetchbuf    */
898         armv4_drain_writebuf,           /* drain_writebuf       */
899         cpufunc_nullop,                 /* flush_brnchtgt_C     */
900         (void *)cpufunc_nullop,         /* flush_brnchtgt_E     */
901
902         xscale_cpu_sleep,               /* sleep                */
903
904         /* Soft functions */
905
906         cpufunc_null_fixup,             /* dataabt_fixup        */
907         cpufunc_null_fixup,             /* prefetchabt_fixup    */
908
909         xscalec3_context_switch,        /* context_switch       */
910
911         xscale_setup                    /* cpu setup            */
912 };
913 #endif /* CPU_XSCALE_81342 */
914
915
916 #if defined(CPU_FA526) || defined(CPU_FA626TE)
917 struct cpu_functions fa526_cpufuncs = {
918         /* CPU functions */
919
920         cpufunc_id,                     /* id                   */
921         cpufunc_nullop,                 /* cpwait               */
922
923         /* MMU functions */
924
925         cpufunc_control,                /* control              */
926         cpufunc_domains,                /* domain               */
927         fa526_setttb,                   /* setttb               */
928         cpufunc_faultstatus,            /* faultstatus          */
929         cpufunc_faultaddress,           /* faultaddress         */
930
931         /* TLB functions */
932
933         armv4_tlb_flushID,              /* tlb_flushID          */
934         fa526_tlb_flushID_SE,           /* tlb_flushID_SE       */
935         armv4_tlb_flushI,               /* tlb_flushI           */
936         fa526_tlb_flushI_SE,            /* tlb_flushI_SE        */
937         armv4_tlb_flushD,               /* tlb_flushD           */
938         armv4_tlb_flushD_SE,            /* tlb_flushD_SE        */
939
940         /* Cache operations */
941
942         fa526_icache_sync_all,          /* icache_sync_all      */
943         fa526_icache_sync_range,        /* icache_sync_range    */
944
945         fa526_dcache_wbinv_all,         /* dcache_wbinv_all     */
946         fa526_dcache_wbinv_range,       /* dcache_wbinv_range   */
947         fa526_dcache_inv_range,         /* dcache_inv_range     */
948         fa526_dcache_wb_range,          /* dcache_wb_range      */
949
950         fa526_idcache_wbinv_all,        /* idcache_wbinv_all    */
951         fa526_idcache_wbinv_range,      /* idcache_wbinv_range  */
952         cpufunc_nullop,                 /* l2cache_wbinv_all    */
953         (void *)cpufunc_nullop,         /* l2cache_wbinv_range  */
954         (void *)cpufunc_nullop,         /* l2cache_inv_range    */
955         (void *)cpufunc_nullop,         /* l2cache_wb_range     */
956
957         /* Other functions */
958
959         fa526_flush_prefetchbuf,        /* flush_prefetchbuf    */
960         armv4_drain_writebuf,           /* drain_writebuf       */
961         cpufunc_nullop,                 /* flush_brnchtgt_C     */
962         fa526_flush_brnchtgt_E,         /* flush_brnchtgt_E     */
963
964         fa526_cpu_sleep,                /* sleep                */
965
966         /* Soft functions */
967
968         cpufunc_null_fixup,             /* dataabt_fixup        */
969         cpufunc_null_fixup,             /* prefetchabt_fixup    */
970
971         fa526_context_switch,           /* context_switch       */
972
973         fa526_setup                     /* cpu setup            */
974 };
975 #endif  /* CPU_FA526 || CPU_FA626TE */
976
977 #if defined(CPU_ARM1136)
978 struct cpu_functions arm1136_cpufuncs = {
979         /* CPU functions */
980         
981         cpufunc_id,                     /* id                   */
982         cpufunc_nullop,                 /* cpwait               */
983         
984         /* MMU functions */
985         
986         cpufunc_control,                /* control              */
987         cpufunc_domains,                /* Domain               */
988         arm11x6_setttb,                 /* Setttb               */
989         cpufunc_faultstatus,            /* Faultstatus          */
990         cpufunc_faultaddress,           /* Faultaddress         */
991         
992         /* TLB functions */
993         
994         arm11_tlb_flushID,              /* tlb_flushID          */
995         arm11_tlb_flushID_SE,           /* tlb_flushID_SE       */
996         arm11_tlb_flushI,               /* tlb_flushI           */
997         arm11_tlb_flushI_SE,            /* tlb_flushI_SE        */
998         arm11_tlb_flushD,               /* tlb_flushD           */
999         arm11_tlb_flushD_SE,            /* tlb_flushD_SE        */
1000         
1001         /* Cache operations */
1002         
1003         arm11x6_icache_sync_all,        /* icache_sync_all      */
1004         arm11x6_icache_sync_range,      /* icache_sync_range    */
1005         
1006         arm11x6_dcache_wbinv_all,       /* dcache_wbinv_all     */
1007         armv6_dcache_wbinv_range,       /* dcache_wbinv_range   */
1008         armv6_dcache_inv_range,         /* dcache_inv_range     */
1009         armv6_dcache_wb_range,          /* dcache_wb_range      */
1010         
1011         arm11x6_idcache_wbinv_all,      /* idcache_wbinv_all    */
1012         arm11x6_idcache_wbinv_range,    /* idcache_wbinv_range  */
1013         
1014         (void *)cpufunc_nullop,         /* l2cache_wbinv_all    */
1015         (void *)cpufunc_nullop,         /* l2cache_wbinv_range  */
1016         (void *)cpufunc_nullop,         /* l2cache_inv_range    */
1017         (void *)cpufunc_nullop,         /* l2cache_wb_range     */
1018         
1019         /* Other functions */
1020         
1021         arm11x6_flush_prefetchbuf,      /* flush_prefetchbuf    */
1022         arm11_drain_writebuf,           /* drain_writebuf       */
1023         cpufunc_nullop,                 /* flush_brnchtgt_C     */
1024         (void *)cpufunc_nullop,         /* flush_brnchtgt_E     */
1025         
1026         arm11_sleep,                    /* sleep                */
1027         
1028         /* Soft functions */
1029         
1030         cpufunc_null_fixup,             /* dataabt_fixup        */
1031         cpufunc_null_fixup,             /* prefetchabt_fixup    */
1032         
1033         arm11_context_switch,           /* context_switch       */
1034         
1035         arm11x6_setup                   /* cpu setup            */
1036 };
1037 #endif /* CPU_ARM1136 */
1038 #if defined(CPU_ARM1176)
1039 struct cpu_functions arm1176_cpufuncs = {
1040         /* CPU functions */
1041         
1042         cpufunc_id,                     /* id                   */
1043         cpufunc_nullop,                 /* cpwait               */
1044         
1045         /* MMU functions */
1046         
1047         cpufunc_control,                /* control              */
1048         cpufunc_domains,                /* Domain               */
1049         arm11x6_setttb,                 /* Setttb               */
1050         cpufunc_faultstatus,            /* Faultstatus          */
1051         cpufunc_faultaddress,           /* Faultaddress         */
1052         
1053         /* TLB functions */
1054         
1055         arm11_tlb_flushID,              /* tlb_flushID          */
1056         arm11_tlb_flushID_SE,           /* tlb_flushID_SE       */
1057         arm11_tlb_flushI,               /* tlb_flushI           */
1058         arm11_tlb_flushI_SE,            /* tlb_flushI_SE        */
1059         arm11_tlb_flushD,               /* tlb_flushD           */
1060         arm11_tlb_flushD_SE,            /* tlb_flushD_SE        */
1061         
1062         /* Cache operations */
1063         
1064         arm11x6_icache_sync_all,        /* icache_sync_all      */
1065         arm11x6_icache_sync_range,      /* icache_sync_range    */
1066         
1067         arm11x6_dcache_wbinv_all,       /* dcache_wbinv_all     */
1068         armv6_dcache_wbinv_range,       /* dcache_wbinv_range   */
1069         armv6_dcache_inv_range,         /* dcache_inv_range     */
1070         armv6_dcache_wb_range,          /* dcache_wb_range      */
1071         
1072         arm11x6_idcache_wbinv_all,      /* idcache_wbinv_all    */
1073         arm11x6_idcache_wbinv_range,    /* idcache_wbinv_range  */
1074         
1075         (void *)cpufunc_nullop,         /* l2cache_wbinv_all    */
1076         (void *)cpufunc_nullop,         /* l2cache_wbinv_range  */
1077         (void *)cpufunc_nullop,         /* l2cache_inv_range    */
1078         (void *)cpufunc_nullop,         /* l2cache_wb_range     */
1079         
1080         /* Other functions */
1081         
1082         arm11x6_flush_prefetchbuf,      /* flush_prefetchbuf    */
1083         arm11_drain_writebuf,           /* drain_writebuf       */
1084         cpufunc_nullop,                 /* flush_brnchtgt_C     */
1085         (void *)cpufunc_nullop,         /* flush_brnchtgt_E     */
1086         
1087         arm11x6_sleep,                  /* sleep                */
1088         
1089         /* Soft functions */
1090         
1091         cpufunc_null_fixup,             /* dataabt_fixup        */
1092         cpufunc_null_fixup,             /* prefetchabt_fixup    */
1093         
1094         arm11_context_switch,           /* context_switch       */
1095         
1096         arm11x6_setup                   /* cpu setup            */
1097 };
1098 #endif /*CPU_ARM1176 */
1099
1100 #if defined(CPU_CORTEXA)
1101 struct cpu_functions cortexa_cpufuncs = {
1102         /* CPU functions */
1103         
1104         cpufunc_id,                     /* id                   */
1105         cpufunc_nullop,                 /* cpwait               */
1106         
1107         /* MMU functions */
1108         
1109         cpufunc_control,                /* control              */
1110         cpufunc_domains,                /* Domain               */
1111         armv7_setttb,                   /* Setttb               */
1112         cpufunc_faultstatus,            /* Faultstatus          */
1113         cpufunc_faultaddress,           /* Faultaddress         */
1114         
1115         /* TLB functions */
1116         
1117         armv7_tlb_flushID,              /* tlb_flushID          */
1118         armv7_tlb_flushID_SE,           /* tlb_flushID_SE       */
1119         arm11_tlb_flushI,               /* tlb_flushI           */
1120         arm11_tlb_flushI_SE,            /* tlb_flushI_SE        */
1121         arm11_tlb_flushD,               /* tlb_flushD           */
1122         arm11_tlb_flushD_SE,            /* tlb_flushD_SE        */
1123         
1124         /* Cache operations */
1125         
1126         armv7_idcache_wbinv_all,         /* icache_sync_all      */
1127         armv7_icache_sync_range,        /* icache_sync_range    */
1128         
1129         armv7_dcache_wbinv_all,         /* dcache_wbinv_all     */
1130         armv7_dcache_wbinv_range,       /* dcache_wbinv_range   */
1131         armv7_dcache_inv_range,         /* dcache_inv_range     */
1132         armv7_dcache_wb_range,          /* dcache_wb_range      */
1133         
1134         armv7_idcache_wbinv_all,        /* idcache_wbinv_all    */
1135         armv7_idcache_wbinv_range,      /* idcache_wbinv_range  */
1136         
1137         /* 
1138          * Note: For CPUs using the PL310 the L2 ops are filled in when the
1139          * L2 cache controller is actually enabled.
1140          */
1141         cpufunc_nullop,                 /* l2cache_wbinv_all    */
1142         (void *)cpufunc_nullop,         /* l2cache_wbinv_range  */
1143         (void *)cpufunc_nullop,         /* l2cache_inv_range    */
1144         (void *)cpufunc_nullop,         /* l2cache_wb_range     */
1145         
1146         /* Other functions */
1147         
1148         cpufunc_nullop,                 /* flush_prefetchbuf    */
1149         armv7_drain_writebuf,           /* drain_writebuf       */
1150         cpufunc_nullop,                 /* flush_brnchtgt_C     */
1151         (void *)cpufunc_nullop,         /* flush_brnchtgt_E     */
1152         
1153         arm11_sleep,                    /* sleep                */
1154         
1155         /* Soft functions */
1156         
1157         cpufunc_null_fixup,             /* dataabt_fixup        */
1158         cpufunc_null_fixup,             /* prefetchabt_fixup    */
1159         
1160         armv7_context_switch,           /* context_switch       */
1161         
1162         cortexa_setup                     /* cpu setup            */
1163 };
1164 #endif /* CPU_CORTEXA */
1165
1166 /*
1167  * Global constants also used by locore.s
1168  */
1169
1170 struct cpu_functions cpufuncs;
1171 u_int cputype;
1172 u_int cpu_reset_needs_v4_MMU_disable;   /* flag used in locore.s */
1173
1174 #if defined(CPU_ARM7TDMI) || defined(CPU_ARM8) || defined(CPU_ARM9) ||  \
1175   defined (CPU_ARM9E) || defined (CPU_ARM10) || defined (CPU_ARM1136) ||        \
1176   defined(CPU_ARM1176) || defined(CPU_XSCALE_80200) || defined(CPU_XSCALE_80321) ||             \
1177   defined(CPU_XSCALE_PXA2X0) || defined(CPU_XSCALE_IXP425) ||           \
1178   defined(CPU_FA526) || defined(CPU_FA626TE) || defined(CPU_MV_PJ4B) ||                 \
1179   defined(CPU_XSCALE_80219) || defined(CPU_XSCALE_81342) || \
1180   defined(CPU_CORTEXA)
1181
1182 static void get_cachetype_cp15(void);
1183
1184 /* Additional cache information local to this file.  Log2 of some of the
1185    above numbers.  */
1186 static int      arm_dcache_l2_nsets;
1187 static int      arm_dcache_l2_assoc;
1188 static int      arm_dcache_l2_linesize;
1189
1190 static void
1191 get_cachetype_cp15()
1192 {
1193         u_int ctype, isize, dsize, cpuid;
1194         u_int clevel, csize, i, sel;
1195         u_int multiplier;
1196         u_char type;
1197
1198         __asm __volatile("mrc p15, 0, %0, c0, c0, 1"
1199                 : "=r" (ctype));
1200
1201         cpuid = cpufunc_id();
1202         /*
1203          * ...and thus spake the ARM ARM:
1204          *
1205          * If an <opcode2> value corresponding to an unimplemented or
1206          * reserved ID register is encountered, the System Control
1207          * processor returns the value of the main ID register.
1208          */
1209         if (ctype == cpuid)
1210                 goto out;
1211
1212         if (CPU_CT_FORMAT(ctype) == CPU_CT_ARMV7) {
1213                 __asm __volatile("mrc p15, 1, %0, c0, c0, 1"
1214                     : "=r" (clevel));
1215                 arm_cache_level = clevel;
1216                 arm_cache_loc = CPU_CLIDR_LOC(arm_cache_level);
1217                 i = 0;
1218                 while ((type = (clevel & 0x7)) && i < 7) {
1219                         if (type == CACHE_DCACHE || type == CACHE_UNI_CACHE ||
1220                             type == CACHE_SEP_CACHE) {
1221                                 sel = i << 1;
1222                                 __asm __volatile("mcr p15, 2, %0, c0, c0, 0"
1223                                     : : "r" (sel));
1224                                 __asm __volatile("mrc p15, 1, %0, c0, c0, 0"
1225                                     : "=r" (csize));
1226                                 arm_cache_type[sel] = csize;
1227                                 arm_dcache_align = 1 << 
1228                                     (CPUV7_CT_xSIZE_LEN(csize) + 4);
1229                                 arm_dcache_align_mask = arm_dcache_align - 1;
1230                         }
1231                         if (type == CACHE_ICACHE || type == CACHE_SEP_CACHE) {
1232                                 sel = (i << 1) | 1;
1233                                 __asm __volatile("mcr p15, 2, %0, c0, c0, 0"
1234                                     : : "r" (sel));
1235                                 __asm __volatile("mrc p15, 1, %0, c0, c0, 0"
1236                                     : "=r" (csize));
1237                                 arm_cache_type[sel] = csize;
1238                         }
1239                         i++;
1240                         clevel >>= 3;
1241                 }
1242         } else {
1243                 if ((ctype & CPU_CT_S) == 0)
1244                         arm_pcache_unified = 1;
1245
1246                 /*
1247                  * If you want to know how this code works, go read the ARM ARM.
1248                  */
1249
1250                 arm_pcache_type = CPU_CT_CTYPE(ctype);
1251
1252                 if (arm_pcache_unified == 0) {
1253                         isize = CPU_CT_ISIZE(ctype);
1254                         multiplier = (isize & CPU_CT_xSIZE_M) ? 3 : 2;
1255                         arm_picache_line_size = 1U << (CPU_CT_xSIZE_LEN(isize) + 3);
1256                         if (CPU_CT_xSIZE_ASSOC(isize) == 0) {
1257                                 if (isize & CPU_CT_xSIZE_M)
1258                                         arm_picache_line_size = 0; /* not present */
1259                                 else
1260                                         arm_picache_ways = 1;
1261                         } else {
1262                                 arm_picache_ways = multiplier <<
1263                                     (CPU_CT_xSIZE_ASSOC(isize) - 1);
1264                         }
1265                         arm_picache_size = multiplier << (CPU_CT_xSIZE_SIZE(isize) + 8);
1266                 }
1267
1268                 dsize = CPU_CT_DSIZE(ctype);
1269                 multiplier = (dsize & CPU_CT_xSIZE_M) ? 3 : 2;
1270                 arm_pdcache_line_size = 1U << (CPU_CT_xSIZE_LEN(dsize) + 3);
1271                 if (CPU_CT_xSIZE_ASSOC(dsize) == 0) {
1272                         if (dsize & CPU_CT_xSIZE_M)
1273                                 arm_pdcache_line_size = 0; /* not present */
1274                         else
1275                                 arm_pdcache_ways = 1;
1276                 } else {
1277                         arm_pdcache_ways = multiplier <<
1278                             (CPU_CT_xSIZE_ASSOC(dsize) - 1);
1279                 }
1280                 arm_pdcache_size = multiplier << (CPU_CT_xSIZE_SIZE(dsize) + 8);
1281
1282                 arm_dcache_align = arm_pdcache_line_size;
1283
1284                 arm_dcache_l2_assoc = CPU_CT_xSIZE_ASSOC(dsize) + multiplier - 2;
1285                 arm_dcache_l2_linesize = CPU_CT_xSIZE_LEN(dsize) + 3;
1286                 arm_dcache_l2_nsets = 6 + CPU_CT_xSIZE_SIZE(dsize) -
1287                     CPU_CT_xSIZE_ASSOC(dsize) - CPU_CT_xSIZE_LEN(dsize);
1288
1289         out:
1290                 arm_dcache_align_mask = arm_dcache_align - 1;
1291         }
1292 }
1293 #endif /* ARM7TDMI || ARM8 || ARM9 || XSCALE */
1294
1295 #if defined(CPU_SA110) || defined(CPU_SA1100) || defined(CPU_SA1110) || \
1296     defined(CPU_IXP12X0)
1297 /* Cache information for CPUs without cache type registers. */
1298 struct cachetab {
1299         u_int32_t ct_cpuid;
1300         int     ct_pcache_type;
1301         int     ct_pcache_unified;
1302         int     ct_pdcache_size;
1303         int     ct_pdcache_line_size;
1304         int     ct_pdcache_ways;
1305         int     ct_picache_size;
1306         int     ct_picache_line_size;
1307         int     ct_picache_ways;
1308 };
1309
1310 struct cachetab cachetab[] = {
1311     /* cpuid,           cache type,       u,  dsiz, ls, wy,  isiz, ls, wy */
1312     /* XXX is this type right for SA-1? */
1313     { CPU_ID_SA110,     CPU_CT_CTYPE_WB1, 0, 16384, 32, 32, 16384, 32, 32 },
1314     { CPU_ID_SA1100,    CPU_CT_CTYPE_WB1, 0,  8192, 32, 32, 16384, 32, 32 },
1315     { CPU_ID_SA1110,    CPU_CT_CTYPE_WB1, 0,  8192, 32, 32, 16384, 32, 32 },
1316     { CPU_ID_IXP1200,   CPU_CT_CTYPE_WB1, 0, 16384, 32, 32, 16384, 32, 32 }, /* XXX */
1317     { 0, 0, 0, 0, 0, 0, 0, 0}
1318 };
1319
1320 static void get_cachetype_table(void);
1321
1322 static void
1323 get_cachetype_table()
1324 {
1325         int i;
1326         u_int32_t cpuid = cpufunc_id();
1327
1328         for (i = 0; cachetab[i].ct_cpuid != 0; i++) {
1329                 if (cachetab[i].ct_cpuid == (cpuid & CPU_ID_CPU_MASK)) {
1330                         arm_pcache_type = cachetab[i].ct_pcache_type;
1331                         arm_pcache_unified = cachetab[i].ct_pcache_unified;
1332                         arm_pdcache_size = cachetab[i].ct_pdcache_size;
1333                         arm_pdcache_line_size =
1334                             cachetab[i].ct_pdcache_line_size;
1335                         arm_pdcache_ways = cachetab[i].ct_pdcache_ways;
1336                         arm_picache_size = cachetab[i].ct_picache_size;
1337                         arm_picache_line_size =
1338                             cachetab[i].ct_picache_line_size;
1339                         arm_picache_ways = cachetab[i].ct_picache_ways;
1340                 }
1341         }
1342         arm_dcache_align = arm_pdcache_line_size;
1343
1344         arm_dcache_align_mask = arm_dcache_align - 1;
1345 }
1346
1347 #endif /* SA110 || SA1100 || SA1111 || IXP12X0 */
1348
1349 /*
1350  * Cannot panic here as we may not have a console yet ...
1351  */
1352
1353 int
1354 set_cpufuncs()
1355 {
1356         cputype = cpufunc_id();
1357         cputype &= CPU_ID_CPU_MASK;
1358
1359         /*
1360          * NOTE: cpu_do_powersave defaults to off.  If we encounter a
1361          * CPU type where we want to use it by default, then we set it.
1362          */
1363
1364 #ifdef CPU_ARM7TDMI
1365         if ((cputype & CPU_ID_IMPLEMENTOR_MASK) == CPU_ID_ARM_LTD &&
1366             CPU_ID_IS7(cputype) &&
1367             (cputype & CPU_ID_7ARCH_MASK) == CPU_ID_7ARCH_V4T) {
1368                 cpufuncs = arm7tdmi_cpufuncs;
1369                 cpu_reset_needs_v4_MMU_disable = 0;
1370                 get_cachetype_cp15();
1371                 pmap_pte_init_generic();
1372                 goto out;
1373         }
1374 #endif  
1375 #ifdef CPU_ARM8
1376         if ((cputype & CPU_ID_IMPLEMENTOR_MASK) == CPU_ID_ARM_LTD &&
1377             (cputype & 0x0000f000) == 0x00008000) {
1378                 cpufuncs = arm8_cpufuncs;
1379                 cpu_reset_needs_v4_MMU_disable = 0;     /* XXX correct? */
1380                 get_cachetype_cp15();
1381                 pmap_pte_init_arm8();
1382                 goto out;
1383         }
1384 #endif  /* CPU_ARM8 */
1385 #ifdef CPU_ARM9
1386         if (((cputype & CPU_ID_IMPLEMENTOR_MASK) == CPU_ID_ARM_LTD ||
1387              (cputype & CPU_ID_IMPLEMENTOR_MASK) == CPU_ID_TI) &&
1388             (cputype & 0x0000f000) == 0x00009000) {
1389                 cpufuncs = arm9_cpufuncs;
1390                 cpu_reset_needs_v4_MMU_disable = 1;     /* V4 or higher */
1391                 get_cachetype_cp15();
1392                 arm9_dcache_sets_inc = 1U << arm_dcache_l2_linesize;
1393                 arm9_dcache_sets_max = (1U << (arm_dcache_l2_linesize +
1394                     arm_dcache_l2_nsets)) - arm9_dcache_sets_inc;
1395                 arm9_dcache_index_inc = 1U << (32 - arm_dcache_l2_assoc);
1396                 arm9_dcache_index_max = 0U - arm9_dcache_index_inc;
1397 #ifdef ARM9_CACHE_WRITE_THROUGH
1398                 pmap_pte_init_arm9();
1399 #else
1400                 pmap_pte_init_generic();
1401 #endif
1402                 goto out;
1403         }
1404 #endif /* CPU_ARM9 */
1405 #if defined(CPU_ARM9E) || defined(CPU_ARM10)
1406         if (cputype == CPU_ID_MV88FR131 || cputype == CPU_ID_MV88FR571_VD ||
1407             cputype == CPU_ID_MV88FR571_41) {
1408                 uint32_t sheeva_ctrl;
1409
1410                 sheeva_ctrl = (MV_DC_STREAM_ENABLE | MV_BTB_DISABLE |
1411                     MV_L2_ENABLE);
1412                 /*
1413                  * Workaround for Marvell MV78100 CPU: Cache prefetch
1414                  * mechanism may affect the cache coherency validity,
1415                  * so it needs to be disabled.
1416                  *
1417                  * Refer to errata document MV-S501058-00C.pdf (p. 3.1
1418                  * L2 Prefetching Mechanism) for details.
1419                  */
1420                 if (cputype == CPU_ID_MV88FR571_VD ||
1421                     cputype == CPU_ID_MV88FR571_41)
1422                         sheeva_ctrl |= MV_L2_PREFETCH_DISABLE;
1423
1424                 sheeva_control_ext(0xffffffff & ~MV_WA_ENABLE, sheeva_ctrl);
1425
1426                 cpufuncs = sheeva_cpufuncs;
1427                 get_cachetype_cp15();
1428                 pmap_pte_init_generic();
1429                 goto out;
1430         } else if (cputype == CPU_ID_ARM926EJS || cputype == CPU_ID_ARM1026EJS) {
1431                 cpufuncs = armv5_ec_cpufuncs;
1432                 get_cachetype_cp15();
1433                 pmap_pte_init_generic();
1434                 goto out;
1435         }
1436 #endif /* CPU_ARM9E || CPU_ARM10 */
1437 #ifdef CPU_ARM10
1438         if (/* cputype == CPU_ID_ARM1020T || */
1439             cputype == CPU_ID_ARM1020E) {
1440                 /*
1441                  * Select write-through cacheing (this isn't really an
1442                  * option on ARM1020T).
1443                  */
1444                 cpufuncs = arm10_cpufuncs;
1445                 cpu_reset_needs_v4_MMU_disable = 1;     /* V4 or higher */
1446                 get_cachetype_cp15();
1447                 arm10_dcache_sets_inc = 1U << arm_dcache_l2_linesize;
1448                 arm10_dcache_sets_max =
1449                     (1U << (arm_dcache_l2_linesize + arm_dcache_l2_nsets)) -
1450                     arm10_dcache_sets_inc;
1451                 arm10_dcache_index_inc = 1U << (32 - arm_dcache_l2_assoc);
1452                 arm10_dcache_index_max = 0U - arm10_dcache_index_inc;
1453                 pmap_pte_init_generic();
1454                 goto out;
1455         }
1456 #endif /* CPU_ARM10 */
1457 #if defined(CPU_ARM1136) || defined(CPU_ARM1176)
1458         if (cputype == CPU_ID_ARM1136JS
1459             || cputype == CPU_ID_ARM1136JSR1
1460             || cputype == CPU_ID_ARM1176JZS) {
1461 #ifdef CPU_ARM1136
1462                 if (cputype == CPU_ID_ARM1136JS
1463                     || cputype == CPU_ID_ARM1136JSR1)
1464                         cpufuncs = arm1136_cpufuncs;
1465 #endif
1466 #ifdef CPU_ARM1176
1467                 if (cputype == CPU_ID_ARM1176JZS)
1468                         cpufuncs = arm1176_cpufuncs;
1469 #endif
1470                 cpu_reset_needs_v4_MMU_disable = 1;     /* V4 or higher */
1471                 get_cachetype_cp15();
1472
1473                 pmap_pte_init_mmu_v6();
1474
1475                 goto out;
1476         }
1477 #endif /* CPU_ARM1136 || CPU_ARM1176 */
1478 #ifdef CPU_CORTEXA
1479         if (cputype == CPU_ID_CORTEXA7 ||
1480             cputype == CPU_ID_CORTEXA8R1 ||
1481             cputype == CPU_ID_CORTEXA8R2 ||
1482             cputype == CPU_ID_CORTEXA8R3 ||
1483             cputype == CPU_ID_CORTEXA9R1 ||
1484             cputype == CPU_ID_CORTEXA9R2 ||
1485             cputype == CPU_ID_CORTEXA9R3 ||
1486             cputype == CPU_ID_CORTEXA15 ) {
1487                 cpufuncs = cortexa_cpufuncs;
1488                 cpu_reset_needs_v4_MMU_disable = 1;     /* V4 or higher */
1489                 get_cachetype_cp15();
1490                 
1491                 pmap_pte_init_mmu_v6();
1492                 /* Use powersave on this CPU. */
1493                 cpu_do_powersave = 1;
1494                 goto out;
1495         }
1496 #endif /* CPU_CORTEXA */
1497                 
1498 #if defined(CPU_MV_PJ4B)
1499         if (cputype == CPU_ID_MV88SV581X_V6 ||
1500             cputype == CPU_ID_MV88SV581X_V7 ||
1501             cputype == CPU_ID_MV88SV584X_V7 ||
1502             cputype == CPU_ID_ARM_88SV581X_V6 ||
1503             cputype == CPU_ID_ARM_88SV581X_V7) {
1504                 if (cpu_pfr(0) & ARM_PFR0_THUMBEE_MASK)
1505                         cpufuncs = pj4bv7_cpufuncs;
1506                 else
1507                         cpufuncs = pj4bv6_cpufuncs;
1508
1509                 get_cachetype_cp15();
1510                 pmap_pte_init_mmu_v6();
1511                 goto out;
1512         } else if (cputype == CPU_ID_ARM_88SV584X_V6 ||
1513             cputype == CPU_ID_MV88SV584X_V6) {
1514                 cpufuncs = pj4bv6_cpufuncs;
1515                 get_cachetype_cp15();
1516                 pmap_pte_init_mmu_v6();
1517                 goto out;
1518         }
1519
1520 #endif /* CPU_MV_PJ4B */
1521 #ifdef CPU_SA110
1522         if (cputype == CPU_ID_SA110) {
1523                 cpufuncs = sa110_cpufuncs;
1524                 cpu_reset_needs_v4_MMU_disable = 1;     /* SA needs it */
1525                 get_cachetype_table();
1526                 pmap_pte_init_sa1();
1527                 goto out;
1528         }
1529 #endif  /* CPU_SA110 */
1530 #ifdef CPU_SA1100
1531         if (cputype == CPU_ID_SA1100) {
1532                 cpufuncs = sa11x0_cpufuncs;
1533                 cpu_reset_needs_v4_MMU_disable = 1;     /* SA needs it  */
1534                 get_cachetype_table();
1535                 pmap_pte_init_sa1();
1536                 /* Use powersave on this CPU. */
1537                 cpu_do_powersave = 1;
1538
1539                 goto out;
1540         }
1541 #endif  /* CPU_SA1100 */
1542 #ifdef CPU_SA1110
1543         if (cputype == CPU_ID_SA1110) {
1544                 cpufuncs = sa11x0_cpufuncs;
1545                 cpu_reset_needs_v4_MMU_disable = 1;     /* SA needs it  */
1546                 get_cachetype_table();
1547                 pmap_pte_init_sa1();
1548                 /* Use powersave on this CPU. */
1549                 cpu_do_powersave = 1;
1550
1551                 goto out;
1552         }
1553 #endif  /* CPU_SA1110 */
1554 #if defined(CPU_FA526) || defined(CPU_FA626TE)
1555         if (cputype == CPU_ID_FA526 || cputype == CPU_ID_FA626TE) {
1556                 cpufuncs = fa526_cpufuncs;
1557                 cpu_reset_needs_v4_MMU_disable = 1;     /* SA needs it  */
1558                 get_cachetype_cp15();
1559                 pmap_pte_init_generic();
1560
1561                 /* Use powersave on this CPU. */
1562                 cpu_do_powersave = 1;
1563
1564                 goto out;
1565         }
1566 #endif  /* CPU_FA526 || CPU_FA626TE */
1567 #ifdef CPU_IXP12X0
1568         if (cputype == CPU_ID_IXP1200) {
1569                 cpufuncs = ixp12x0_cpufuncs;
1570                 cpu_reset_needs_v4_MMU_disable = 1;
1571                 get_cachetype_table();
1572                 pmap_pte_init_sa1();
1573                 goto out;
1574         }
1575 #endif  /* CPU_IXP12X0 */
1576 #ifdef CPU_XSCALE_80200
1577         if (cputype == CPU_ID_80200) {
1578                 int rev = cpufunc_id() & CPU_ID_REVISION_MASK;
1579
1580                 i80200_icu_init();
1581
1582 #if defined(XSCALE_CCLKCFG)
1583                 /*
1584                  * Crank CCLKCFG to maximum legal value.
1585                  */
1586                 __asm __volatile ("mcr p14, 0, %0, c6, c0, 0"
1587                         :
1588                         : "r" (XSCALE_CCLKCFG));
1589 #endif
1590
1591                 /*
1592                  * XXX Disable ECC in the Bus Controller Unit; we
1593                  * don't really support it, yet.  Clear any pending
1594                  * error indications.
1595                  */
1596                 __asm __volatile("mcr p13, 0, %0, c0, c1, 0"
1597                         :
1598                         : "r" (BCUCTL_E0|BCUCTL_E1|BCUCTL_EV));
1599
1600                 cpufuncs = xscale_cpufuncs;
1601                 /*
1602                  * i80200 errata: Step-A0 and A1 have a bug where
1603                  * D$ dirty bits are not cleared on "invalidate by
1604                  * address".
1605                  *
1606                  * Workaround: Clean cache line before invalidating.
1607                  */
1608                 if (rev == 0 || rev == 1)
1609                         cpufuncs.cf_dcache_inv_range = xscale_cache_purgeD_rng;
1610
1611                 cpu_reset_needs_v4_MMU_disable = 1;     /* XScale needs it */
1612                 get_cachetype_cp15();
1613                 pmap_pte_init_xscale();
1614                 goto out;
1615         }
1616 #endif /* CPU_XSCALE_80200 */
1617 #if defined(CPU_XSCALE_80321) || defined(CPU_XSCALE_80219)
1618         if (cputype == CPU_ID_80321_400 || cputype == CPU_ID_80321_600 ||
1619             cputype == CPU_ID_80321_400_B0 || cputype == CPU_ID_80321_600_B0 ||
1620             cputype == CPU_ID_80219_400 || cputype == CPU_ID_80219_600) {
1621                 cpufuncs = xscale_cpufuncs;
1622                 cpu_reset_needs_v4_MMU_disable = 1;     /* XScale needs it */
1623                 get_cachetype_cp15();
1624                 pmap_pte_init_xscale();
1625                 goto out;
1626         }
1627 #endif /* CPU_XSCALE_80321 */
1628
1629 #if defined(CPU_XSCALE_81342)
1630         if (cputype == CPU_ID_81342) {
1631                 cpufuncs = xscalec3_cpufuncs;
1632                 cpu_reset_needs_v4_MMU_disable = 1;     /* XScale needs it */
1633                 get_cachetype_cp15();
1634                 pmap_pte_init_xscale();
1635                 goto out;
1636         }
1637 #endif /* CPU_XSCALE_81342 */
1638 #ifdef CPU_XSCALE_PXA2X0
1639         /* ignore core revision to test PXA2xx CPUs */
1640         if ((cputype & ~CPU_ID_XSCALE_COREREV_MASK) == CPU_ID_PXA250 ||
1641             (cputype & ~CPU_ID_XSCALE_COREREV_MASK) == CPU_ID_PXA27X ||
1642             (cputype & ~CPU_ID_XSCALE_COREREV_MASK) == CPU_ID_PXA210) {
1643
1644                 cpufuncs = xscale_cpufuncs;
1645                 cpu_reset_needs_v4_MMU_disable = 1;     /* XScale needs it */
1646                 get_cachetype_cp15();
1647                 pmap_pte_init_xscale();
1648
1649                 /* Use powersave on this CPU. */
1650                 cpu_do_powersave = 1;
1651
1652                 goto out;
1653         }
1654 #endif /* CPU_XSCALE_PXA2X0 */
1655 #ifdef CPU_XSCALE_IXP425
1656         if (cputype == CPU_ID_IXP425_533 || cputype == CPU_ID_IXP425_400 ||
1657             cputype == CPU_ID_IXP425_266 || cputype == CPU_ID_IXP435) {
1658
1659                 cpufuncs = xscale_cpufuncs;
1660                 cpu_reset_needs_v4_MMU_disable = 1;     /* XScale needs it */
1661                 get_cachetype_cp15();
1662                 pmap_pte_init_xscale();
1663
1664                 goto out;
1665         }
1666 #endif /* CPU_XSCALE_IXP425 */
1667         /*
1668          * Bzzzz. And the answer was ...
1669          */
1670         panic("No support for this CPU type (%08x) in kernel", cputype);
1671         return(ARCHITECTURE_NOT_PRESENT);
1672 out:
1673         uma_set_align(arm_dcache_align_mask);
1674         return (0);
1675 }
1676
1677 /*
1678  * Fixup routines for data and prefetch aborts.
1679  *
1680  * Several compile time symbols are used
1681  *
1682  * DEBUG_FAULT_CORRECTION - Print debugging information during the
1683  * correction of registers after a fault.
1684  * ARM6_LATE_ABORT - ARM6 supports both early and late aborts
1685  * when defined should use late aborts
1686  */
1687
1688
1689 /*
1690  * Null abort fixup routine.
1691  * For use when no fixup is required.
1692  */
1693 int
1694 cpufunc_null_fixup(arg)
1695         void *arg;
1696 {
1697         return(ABORT_FIXUP_OK);
1698 }
1699
1700
1701 #if defined(CPU_ARM7TDMI)
1702
1703 #ifdef DEBUG_FAULT_CORRECTION
1704 #define DFC_PRINTF(x)           printf x
1705 #define DFC_DISASSEMBLE(x)      disassemble(x)
1706 #else
1707 #define DFC_PRINTF(x)           /* nothing */
1708 #define DFC_DISASSEMBLE(x)      /* nothing */
1709 #endif
1710
1711 /*
1712  * "Early" data abort fixup.
1713  *
1714  * For ARM2, ARM2as, ARM3 and ARM6 (in early-abort mode).  Also used
1715  * indirectly by ARM6 (in late-abort mode) and ARM7[TDMI].
1716  *
1717  * In early aborts, we may have to fix up LDM, STM, LDC and STC.
1718  */
1719 int
1720 early_abort_fixup(arg)
1721         void *arg;
1722 {
1723         trapframe_t *frame = arg;
1724         u_int fault_pc;
1725         u_int fault_instruction;
1726         int saved_lr = 0;
1727
1728         if ((frame->tf_spsr & PSR_MODE) == PSR_SVC32_MODE) {
1729
1730                 /* Ok an abort in SVC mode */
1731
1732                 /*
1733                  * Copy the SVC r14 into the usr r14 - The usr r14 is garbage
1734                  * as the fault happened in svc mode but we need it in the
1735                  * usr slot so we can treat the registers as an array of ints
1736                  * during fixing.
1737                  * NOTE: This PC is in the position but writeback is not
1738                  * allowed on r15.
1739                  * Doing it like this is more efficient than trapping this
1740                  * case in all possible locations in the following fixup code.
1741                  */
1742
1743                 saved_lr = frame->tf_usr_lr;
1744                 frame->tf_usr_lr = frame->tf_svc_lr;
1745
1746                 /*
1747                  * Note the trapframe does not have the SVC r13 so a fault
1748                  * from an instruction with writeback to r13 in SVC mode is
1749                  * not allowed. This should not happen as the kstack is
1750                  * always valid.
1751                  */
1752         }
1753
1754         /* Get fault address and status from the CPU */
1755
1756         fault_pc = frame->tf_pc;
1757         fault_instruction = *((volatile unsigned int *)fault_pc);
1758
1759         /* Decode the fault instruction and fix the registers as needed */
1760
1761         if ((fault_instruction & 0x0e000000) == 0x08000000) {
1762                 int base;
1763                 int loop;
1764                 int count;
1765                 int *registers = &frame->tf_r0;
1766
1767                 DFC_PRINTF(("LDM/STM\n"));
1768                 DFC_DISASSEMBLE(fault_pc);
1769                 if (fault_instruction & (1 << 21)) {
1770                         DFC_PRINTF(("This instruction must be corrected\n"));
1771                         base = (fault_instruction >> 16) & 0x0f;
1772                         if (base == 15)
1773                                 return ABORT_FIXUP_FAILED;
1774                         /* Count registers transferred */
1775                         count = 0;
1776                         for (loop = 0; loop < 16; ++loop) {
1777                                 if (fault_instruction & (1<<loop))
1778                                         ++count;
1779                         }
1780                         DFC_PRINTF(("%d registers used\n", count));
1781                         DFC_PRINTF(("Corrected r%d by %d bytes ",
1782                                        base, count * 4));
1783                         if (fault_instruction & (1 << 23)) {
1784                                 DFC_PRINTF(("down\n"));
1785                                 registers[base] -= count * 4;
1786                         } else {
1787                                 DFC_PRINTF(("up\n"));
1788                                 registers[base] += count * 4;
1789                         }
1790                 }
1791         } else if ((fault_instruction & 0x0e000000) == 0x0c000000) {
1792                 int base;
1793                 int offset;
1794                 int *registers = &frame->tf_r0;
1795         
1796                 /* REGISTER CORRECTION IS REQUIRED FOR THESE INSTRUCTIONS */
1797
1798                 DFC_DISASSEMBLE(fault_pc);
1799
1800                 /* Only need to fix registers if write back is turned on */
1801
1802                 if ((fault_instruction & (1 << 21)) != 0) {
1803                         base = (fault_instruction >> 16) & 0x0f;
1804                         if (base == 13 &&
1805                             (frame->tf_spsr & PSR_MODE) == PSR_SVC32_MODE)
1806                                 return ABORT_FIXUP_FAILED;
1807                         if (base == 15)
1808                                 return ABORT_FIXUP_FAILED;
1809
1810                         offset = (fault_instruction & 0xff) << 2;
1811                         DFC_PRINTF(("r%d=%08x\n", base, registers[base]));
1812                         if ((fault_instruction & (1 << 23)) != 0)
1813                                 offset = -offset;
1814                         registers[base] += offset;
1815                         DFC_PRINTF(("r%d=%08x\n", base, registers[base]));
1816                 }
1817         } else if ((fault_instruction & 0x0e000000) == 0x0c000000)
1818                 return ABORT_FIXUP_FAILED;
1819
1820         if ((frame->tf_spsr & PSR_MODE) == PSR_SVC32_MODE) {
1821
1822                 /* Ok an abort in SVC mode */
1823
1824                 /*
1825                  * Copy the SVC r14 into the usr r14 - The usr r14 is garbage
1826                  * as the fault happened in svc mode but we need it in the
1827                  * usr slot so we can treat the registers as an array of ints
1828                  * during fixing.
1829                  * NOTE: This PC is in the position but writeback is not
1830                  * allowed on r15.
1831                  * Doing it like this is more efficient than trapping this
1832                  * case in all possible locations in the prior fixup code.
1833                  */
1834
1835                 frame->tf_svc_lr = frame->tf_usr_lr;
1836                 frame->tf_usr_lr = saved_lr;
1837
1838                 /*
1839                  * Note the trapframe does not have the SVC r13 so a fault
1840                  * from an instruction with writeback to r13 in SVC mode is
1841                  * not allowed. This should not happen as the kstack is
1842                  * always valid.
1843                  */
1844         }
1845
1846         return(ABORT_FIXUP_OK);
1847 }
1848 #endif  /* CPU_ARM2/250/3/6/7 */
1849
1850
1851 #if defined(CPU_ARM7TDMI)
1852 /*
1853  * "Late" (base updated) data abort fixup
1854  *
1855  * For ARM6 (in late-abort mode) and ARM7.
1856  *
1857  * In this model, all data-transfer instructions need fixing up.  We defer
1858  * LDM, STM, LDC and STC fixup to the early-abort handler.
1859  */
1860 int
1861 late_abort_fixup(arg)
1862         void *arg;
1863 {
1864         trapframe_t *frame = arg;
1865         u_int fault_pc;
1866         u_int fault_instruction;
1867         int saved_lr = 0;
1868
1869         if ((frame->tf_spsr & PSR_MODE) == PSR_SVC32_MODE) {
1870
1871                 /* Ok an abort in SVC mode */
1872
1873                 /*
1874                  * Copy the SVC r14 into the usr r14 - The usr r14 is garbage
1875                  * as the fault happened in svc mode but we need it in the
1876                  * usr slot so we can treat the registers as an array of ints
1877                  * during fixing.
1878                  * NOTE: This PC is in the position but writeback is not
1879                  * allowed on r15.
1880                  * Doing it like this is more efficient than trapping this
1881                  * case in all possible locations in the following fixup code.
1882                  */
1883
1884                 saved_lr = frame->tf_usr_lr;
1885                 frame->tf_usr_lr = frame->tf_svc_lr;
1886
1887                 /*
1888                  * Note the trapframe does not have the SVC r13 so a fault
1889                  * from an instruction with writeback to r13 in SVC mode is
1890                  * not allowed. This should not happen as the kstack is
1891                  * always valid.
1892                  */
1893         }
1894
1895         /* Get fault address and status from the CPU */
1896
1897         fault_pc = frame->tf_pc;
1898         fault_instruction = *((volatile unsigned int *)fault_pc);
1899
1900         /* Decode the fault instruction and fix the registers as needed */
1901
1902         /* Was is a swap instruction ? */
1903
1904         if ((fault_instruction & 0x0fb00ff0) == 0x01000090) {
1905                 DFC_DISASSEMBLE(fault_pc);
1906         } else if ((fault_instruction & 0x0c000000) == 0x04000000) {
1907
1908                 /* Was is a ldr/str instruction */
1909                 /* This is for late abort only */
1910
1911                 int base;
1912                 int offset;
1913                 int *registers = &frame->tf_r0;
1914
1915                 DFC_DISASSEMBLE(fault_pc);
1916                 
1917                 /* This is for late abort only */
1918
1919                 if ((fault_instruction & (1 << 24)) == 0
1920                     || (fault_instruction & (1 << 21)) != 0) {  
1921                         /* postindexed ldr/str with no writeback */
1922
1923                         base = (fault_instruction >> 16) & 0x0f;
1924                         if (base == 13 &&
1925                             (frame->tf_spsr & PSR_MODE) == PSR_SVC32_MODE)
1926                                 return ABORT_FIXUP_FAILED;
1927                         if (base == 15)
1928                                 return ABORT_FIXUP_FAILED;
1929                         DFC_PRINTF(("late abt fix: r%d=%08x : ",
1930                                        base, registers[base]));
1931                         if ((fault_instruction & (1 << 25)) == 0) {
1932                                 /* Immediate offset - easy */
1933
1934                                 offset = fault_instruction & 0xfff;
1935                                 if ((fault_instruction & (1 << 23)))
1936                                         offset = -offset;
1937                                 registers[base] += offset;
1938                                 DFC_PRINTF(("imm=%08x ", offset));
1939                         } else {
1940                                 /* offset is a shifted register */
1941                                 int shift;
1942
1943                                 offset = fault_instruction & 0x0f;
1944                                 if (offset == base)
1945                                         return ABORT_FIXUP_FAILED;
1946
1947                                 /*
1948                                  * Register offset - hard we have to
1949                                  * cope with shifts !
1950                                  */
1951                                 offset = registers[offset];
1952
1953                                 if ((fault_instruction & (1 << 4)) == 0)
1954                                         /* shift with amount */
1955                                         shift = (fault_instruction >> 7) & 0x1f;
1956                                 else {
1957                                         /* shift with register */
1958                                         if ((fault_instruction & (1 << 7)) != 0)
1959                                                 /* undefined for now so bail out */
1960                                                 return ABORT_FIXUP_FAILED;
1961                                         shift = ((fault_instruction >> 8) & 0xf);
1962                                         if (base == shift)
1963                                                 return ABORT_FIXUP_FAILED;
1964                                         DFC_PRINTF(("shift reg=%d ", shift));
1965                                         shift = registers[shift];
1966                                 }
1967                                 DFC_PRINTF(("shift=%08x ", shift));
1968                                 switch (((fault_instruction >> 5) & 0x3)) {
1969                                 case 0 : /* Logical left */
1970                                         offset = (int)(((u_int)offset) << shift);
1971                                         break;
1972                                 case 1 : /* Logical Right */
1973                                         if (shift == 0) shift = 32;
1974                                         offset = (int)(((u_int)offset) >> shift);
1975                                         break;
1976                                 case 2 : /* Arithmetic Right */
1977                                         if (shift == 0) shift = 32;
1978                                         offset = (int)(((int)offset) >> shift);
1979                                         break;
1980                                 case 3 : /* Rotate right (rol or rxx) */
1981                                         return ABORT_FIXUP_FAILED;
1982                                         break;
1983                                 }
1984
1985                                 DFC_PRINTF(("abt: fixed LDR/STR with "
1986                                                "register offset\n"));
1987                                 if ((fault_instruction & (1 << 23)))
1988                                         offset = -offset;
1989                                 DFC_PRINTF(("offset=%08x ", offset));
1990                                 registers[base] += offset;
1991                         }
1992                         DFC_PRINTF(("r%d=%08x\n", base, registers[base]));
1993                 }
1994         }
1995
1996         if ((frame->tf_spsr & PSR_MODE) == PSR_SVC32_MODE) {
1997
1998                 /* Ok an abort in SVC mode */
1999
2000                 /*
2001                  * Copy the SVC r14 into the usr r14 - The usr r14 is garbage
2002                  * as the fault happened in svc mode but we need it in the
2003                  * usr slot so we can treat the registers as an array of ints
2004                  * during fixing.
2005                  * NOTE: This PC is in the position but writeback is not
2006                  * allowed on r15.
2007                  * Doing it like this is more efficient than trapping this
2008                  * case in all possible locations in the prior fixup code.
2009                  */
2010
2011                 frame->tf_svc_lr = frame->tf_usr_lr;
2012                 frame->tf_usr_lr = saved_lr;
2013
2014                 /*
2015                  * Note the trapframe does not have the SVC r13 so a fault
2016                  * from an instruction with writeback to r13 in SVC mode is
2017                  * not allowed. This should not happen as the kstack is
2018                  * always valid.
2019                  */
2020         }
2021
2022         /*
2023          * Now let the early-abort fixup routine have a go, in case it
2024          * was an LDM, STM, LDC or STC that faulted.
2025          */
2026
2027         return early_abort_fixup(arg);
2028 }
2029 #endif  /* CPU_ARM7TDMI */
2030
2031 /*
2032  * CPU Setup code
2033  */
2034
2035 #if defined(CPU_ARM7TDMI) || defined(CPU_ARM8) || defined (CPU_ARM9) || \
2036   defined(CPU_ARM9E) || \
2037   defined(CPU_SA110) || defined(CPU_SA1100) || defined(CPU_SA1110) ||   \
2038   defined(CPU_XSCALE_80200) || defined(CPU_XSCALE_80321) ||             \
2039   defined(CPU_XSCALE_PXA2X0) || defined(CPU_XSCALE_IXP425) ||           \
2040   defined(CPU_XSCALE_80219) || defined(CPU_XSCALE_81342) || \
2041   defined(CPU_ARM10) ||  defined(CPU_ARM1136) || defined(CPU_ARM1176) ||\
2042   defined(CPU_FA526) || defined(CPU_FA626TE)
2043
2044 #define IGN     0
2045 #define OR      1
2046 #define BIC     2
2047
2048 struct cpu_option {
2049         char    *co_name;
2050         int     co_falseop;
2051         int     co_trueop;
2052         int     co_value;
2053 };
2054
2055 static u_int parse_cpu_options(char *, struct cpu_option *, u_int);
2056
2057 static u_int
2058 parse_cpu_options(args, optlist, cpuctrl)
2059         char *args;
2060         struct cpu_option *optlist;
2061         u_int cpuctrl;
2062 {
2063         int integer;
2064
2065         if (args == NULL)
2066                 return(cpuctrl);
2067
2068         while (optlist->co_name) {
2069                 if (get_bootconf_option(args, optlist->co_name,
2070                     BOOTOPT_TYPE_BOOLEAN, &integer)) {
2071                         if (integer) {
2072                                 if (optlist->co_trueop == OR)
2073                                         cpuctrl |= optlist->co_value;
2074                                 else if (optlist->co_trueop == BIC)
2075                                         cpuctrl &= ~optlist->co_value;
2076                         } else {
2077                                 if (optlist->co_falseop == OR)
2078                                         cpuctrl |= optlist->co_value;
2079                                 else if (optlist->co_falseop == BIC)
2080                                         cpuctrl &= ~optlist->co_value;
2081                         }
2082                 }
2083                 ++optlist;
2084         }
2085         return(cpuctrl);
2086 }
2087 #endif /* CPU_ARM7TDMI || CPU_ARM8 || CPU_SA110 || XSCALE*/
2088
2089 #if defined(CPU_ARM7TDMI) || defined(CPU_ARM8)
2090 struct cpu_option arm678_options[] = {
2091 #ifdef COMPAT_12
2092         { "nocache",            IGN, BIC, CPU_CONTROL_IDC_ENABLE },
2093         { "nowritebuf",         IGN, BIC, CPU_CONTROL_WBUF_ENABLE },
2094 #endif  /* COMPAT_12 */
2095         { "cpu.cache",          BIC, OR,  CPU_CONTROL_IDC_ENABLE },
2096         { "cpu.nocache",        OR,  BIC, CPU_CONTROL_IDC_ENABLE },
2097         { "cpu.writebuf",       BIC, OR,  CPU_CONTROL_WBUF_ENABLE },
2098         { "cpu.nowritebuf",     OR,  BIC, CPU_CONTROL_WBUF_ENABLE },
2099         { NULL,                 IGN, IGN, 0 }
2100 };
2101
2102 #endif  /* CPU_ARM6 || CPU_ARM7 || CPU_ARM7TDMI || CPU_ARM8 */
2103
2104 #ifdef CPU_ARM7TDMI
2105 struct cpu_option arm7tdmi_options[] = {
2106         { "arm7.cache",         BIC, OR,  CPU_CONTROL_IDC_ENABLE },
2107         { "arm7.nocache",       OR,  BIC, CPU_CONTROL_IDC_ENABLE },
2108         { "arm7.writebuf",      BIC, OR,  CPU_CONTROL_WBUF_ENABLE },
2109         { "arm7.nowritebuf",    OR,  BIC, CPU_CONTROL_WBUF_ENABLE },
2110 #ifdef COMPAT_12
2111         { "fpaclk2",            BIC, OR,  CPU_CONTROL_CPCLK },
2112 #endif  /* COMPAT_12 */
2113         { "arm700.fpaclk",      BIC, OR,  CPU_CONTROL_CPCLK },
2114         { NULL,                 IGN, IGN, 0 }
2115 };
2116
2117 void
2118 arm7tdmi_setup(args)
2119         char *args;
2120 {
2121         int cpuctrl;
2122
2123         cpuctrl = CPU_CONTROL_MMU_ENABLE | CPU_CONTROL_32BP_ENABLE
2124                  | CPU_CONTROL_32BD_ENABLE | CPU_CONTROL_SYST_ENABLE
2125                  | CPU_CONTROL_IDC_ENABLE | CPU_CONTROL_WBUF_ENABLE;
2126
2127         cpuctrl = parse_cpu_options(args, arm678_options, cpuctrl);
2128         cpuctrl = parse_cpu_options(args, arm7tdmi_options, cpuctrl);
2129
2130 #ifdef __ARMEB__
2131         cpuctrl |= CPU_CONTROL_BEND_ENABLE;
2132 #endif
2133
2134         /* Clear out the cache */
2135         cpu_idcache_wbinv_all();
2136
2137         /* Set the control register */
2138         ctrl = cpuctrl;
2139         cpu_control(0xffffffff, cpuctrl);
2140 }
2141 #endif  /* CPU_ARM7TDMI */
2142
2143 #ifdef CPU_ARM8
2144 struct cpu_option arm8_options[] = {
2145         { "arm8.cache",         BIC, OR,  CPU_CONTROL_IDC_ENABLE },
2146         { "arm8.nocache",       OR,  BIC, CPU_CONTROL_IDC_ENABLE },
2147         { "arm8.writebuf",      BIC, OR,  CPU_CONTROL_WBUF_ENABLE },
2148         { "arm8.nowritebuf",    OR,  BIC, CPU_CONTROL_WBUF_ENABLE },
2149 #ifdef COMPAT_12
2150         { "branchpredict",      BIC, OR,  CPU_CONTROL_BPRD_ENABLE },
2151 #endif  /* COMPAT_12 */
2152         { "cpu.branchpredict",  BIC, OR,  CPU_CONTROL_BPRD_ENABLE },
2153         { "arm8.branchpredict", BIC, OR,  CPU_CONTROL_BPRD_ENABLE },
2154         { NULL,                 IGN, IGN, 0 }
2155 };
2156
2157 void
2158 arm8_setup(args)
2159         char *args;
2160 {
2161         int integer;
2162         int cpuctrl, cpuctrlmask;
2163         int clocktest;
2164         int setclock = 0;
2165
2166         cpuctrl = CPU_CONTROL_MMU_ENABLE | CPU_CONTROL_32BP_ENABLE
2167                  | CPU_CONTROL_32BD_ENABLE | CPU_CONTROL_SYST_ENABLE
2168                  | CPU_CONTROL_IDC_ENABLE | CPU_CONTROL_WBUF_ENABLE;
2169         cpuctrlmask = CPU_CONTROL_MMU_ENABLE | CPU_CONTROL_32BP_ENABLE
2170                  | CPU_CONTROL_32BD_ENABLE | CPU_CONTROL_SYST_ENABLE
2171                  | CPU_CONTROL_IDC_ENABLE | CPU_CONTROL_WBUF_ENABLE
2172                  | CPU_CONTROL_BPRD_ENABLE | CPU_CONTROL_ROM_ENABLE
2173                  | CPU_CONTROL_BEND_ENABLE | CPU_CONTROL_AFLT_ENABLE;
2174
2175 #ifndef ARM32_DISABLE_ALIGNMENT_FAULTS
2176         cpuctrl |= CPU_CONTROL_AFLT_ENABLE;
2177 #endif
2178
2179         cpuctrl = parse_cpu_options(args, arm678_options, cpuctrl);
2180         cpuctrl = parse_cpu_options(args, arm8_options, cpuctrl);
2181
2182 #ifdef __ARMEB__
2183         cpuctrl |= CPU_CONTROL_BEND_ENABLE;
2184 #endif
2185
2186         /* Get clock configuration */
2187         clocktest = arm8_clock_config(0, 0) & 0x0f;
2188
2189         /* Special ARM8 clock and test configuration */
2190         if (get_bootconf_option(args, "arm8.clock.reset", BOOTOPT_TYPE_BOOLEAN, &integer)) {
2191                 clocktest = 0;
2192                 setclock = 1;
2193         }
2194         if (get_bootconf_option(args, "arm8.clock.dynamic", BOOTOPT_TYPE_BOOLEAN, &integer)) {
2195                 if (integer)
2196                         clocktest |= 0x01;
2197                 else
2198                         clocktest &= ~(0x01);
2199                 setclock = 1;
2200         }
2201         if (get_bootconf_option(args, "arm8.clock.sync", BOOTOPT_TYPE_BOOLEAN, &integer)) {
2202                 if (integer)
2203                         clocktest |= 0x02;
2204                 else
2205                         clocktest &= ~(0x02);
2206                 setclock = 1;
2207         }
2208         if (get_bootconf_option(args, "arm8.clock.fast", BOOTOPT_TYPE_BININT, &integer)) {
2209                 clocktest = (clocktest & ~0xc0) | (integer & 3) << 2;
2210                 setclock = 1;
2211         }
2212         if (get_bootconf_option(args, "arm8.test", BOOTOPT_TYPE_BININT, &integer)) {
2213                 clocktest |= (integer & 7) << 5;
2214                 setclock = 1;
2215         }
2216         
2217         /* Clear out the cache */
2218         cpu_idcache_wbinv_all();
2219
2220         /* Set the control register */
2221         ctrl = cpuctrl;
2222         cpu_control(0xffffffff, cpuctrl);
2223
2224         /* Set the clock/test register */
2225         if (setclock)
2226                 arm8_clock_config(0x7f, clocktest);
2227 }
2228 #endif  /* CPU_ARM8 */
2229
2230 #ifdef CPU_ARM9
2231 struct cpu_option arm9_options[] = {
2232         { "cpu.cache",          BIC, OR,  (CPU_CONTROL_IC_ENABLE | CPU_CONTROL_DC_ENABLE) },
2233         { "cpu.nocache",        OR,  BIC, (CPU_CONTROL_IC_ENABLE | CPU_CONTROL_DC_ENABLE) },
2234         { "arm9.cache", BIC, OR,  (CPU_CONTROL_IC_ENABLE | CPU_CONTROL_DC_ENABLE) },
2235         { "arm9.icache",        BIC, OR,  CPU_CONTROL_IC_ENABLE },
2236         { "arm9.dcache",        BIC, OR,  CPU_CONTROL_DC_ENABLE },
2237         { "cpu.writebuf",       BIC, OR,  CPU_CONTROL_WBUF_ENABLE },
2238         { "cpu.nowritebuf",     OR,  BIC, CPU_CONTROL_WBUF_ENABLE },
2239         { "arm9.writebuf",      BIC, OR,  CPU_CONTROL_WBUF_ENABLE },
2240         { NULL,                 IGN, IGN, 0 }
2241 };
2242
2243 void
2244 arm9_setup(args)
2245         char *args;
2246 {
2247         int cpuctrl, cpuctrlmask;
2248
2249         cpuctrl = CPU_CONTROL_MMU_ENABLE | CPU_CONTROL_32BP_ENABLE
2250             | CPU_CONTROL_32BD_ENABLE | CPU_CONTROL_SYST_ENABLE
2251             | CPU_CONTROL_IC_ENABLE | CPU_CONTROL_DC_ENABLE
2252             | CPU_CONTROL_WBUF_ENABLE | CPU_CONTROL_LABT_ENABLE |
2253             CPU_CONTROL_ROUNDROBIN;
2254         cpuctrlmask = CPU_CONTROL_MMU_ENABLE | CPU_CONTROL_32BP_ENABLE
2255                  | CPU_CONTROL_32BD_ENABLE | CPU_CONTROL_SYST_ENABLE
2256                  | CPU_CONTROL_IC_ENABLE | CPU_CONTROL_DC_ENABLE
2257                  | CPU_CONTROL_WBUF_ENABLE | CPU_CONTROL_ROM_ENABLE
2258                  | CPU_CONTROL_BEND_ENABLE | CPU_CONTROL_AFLT_ENABLE
2259                  | CPU_CONTROL_LABT_ENABLE | CPU_CONTROL_VECRELOC
2260                  | CPU_CONTROL_ROUNDROBIN;
2261
2262 #ifndef ARM32_DISABLE_ALIGNMENT_FAULTS
2263         cpuctrl |= CPU_CONTROL_AFLT_ENABLE;
2264 #endif
2265
2266         cpuctrl = parse_cpu_options(args, arm9_options, cpuctrl);
2267
2268 #ifdef __ARMEB__
2269         cpuctrl |= CPU_CONTROL_BEND_ENABLE;
2270 #endif
2271         if (vector_page == ARM_VECTORS_HIGH)
2272                 cpuctrl |= CPU_CONTROL_VECRELOC;
2273
2274         /* Clear out the cache */
2275         cpu_idcache_wbinv_all();
2276
2277         /* Set the control register */
2278         cpu_control(cpuctrlmask, cpuctrl);
2279         ctrl = cpuctrl;
2280
2281 }
2282 #endif  /* CPU_ARM9 */
2283
2284 #if defined(CPU_ARM9E) || defined(CPU_ARM10)
2285 struct cpu_option arm10_options[] = {
2286         { "cpu.cache",          BIC, OR,  (CPU_CONTROL_IC_ENABLE | CPU_CONTROL_DC_ENABLE) },
2287         { "cpu.nocache",        OR,  BIC, (CPU_CONTROL_IC_ENABLE | CPU_CONTROL_DC_ENABLE) },
2288         { "arm10.cache",        BIC, OR,  (CPU_CONTROL_IC_ENABLE | CPU_CONTROL_DC_ENABLE) },
2289         { "arm10.icache",       BIC, OR,  CPU_CONTROL_IC_ENABLE },
2290         { "arm10.dcache",       BIC, OR,  CPU_CONTROL_DC_ENABLE },
2291         { "cpu.writebuf",       BIC, OR,  CPU_CONTROL_WBUF_ENABLE },
2292         { "cpu.nowritebuf",     OR,  BIC, CPU_CONTROL_WBUF_ENABLE },
2293         { "arm10.writebuf",     BIC, OR,  CPU_CONTROL_WBUF_ENABLE },
2294         { NULL,                 IGN, IGN, 0 }
2295 };
2296
2297 void
2298 arm10_setup(args)
2299         char *args;
2300 {
2301         int cpuctrl, cpuctrlmask;
2302
2303         cpuctrl = CPU_CONTROL_MMU_ENABLE | CPU_CONTROL_SYST_ENABLE
2304             | CPU_CONTROL_IC_ENABLE | CPU_CONTROL_DC_ENABLE
2305             | CPU_CONTROL_WBUF_ENABLE | CPU_CONTROL_BPRD_ENABLE;
2306         cpuctrlmask = CPU_CONTROL_MMU_ENABLE | CPU_CONTROL_SYST_ENABLE
2307             | CPU_CONTROL_IC_ENABLE | CPU_CONTROL_DC_ENABLE
2308             | CPU_CONTROL_WBUF_ENABLE | CPU_CONTROL_ROM_ENABLE
2309             | CPU_CONTROL_BEND_ENABLE | CPU_CONTROL_AFLT_ENABLE
2310             | CPU_CONTROL_BPRD_ENABLE
2311             | CPU_CONTROL_ROUNDROBIN | CPU_CONTROL_CPCLK;
2312
2313 #ifndef ARM32_DISABLE_ALIGNMENT_FAULTS
2314         cpuctrl |= CPU_CONTROL_AFLT_ENABLE;
2315 #endif
2316
2317         cpuctrl = parse_cpu_options(args, arm10_options, cpuctrl);
2318
2319 #ifdef __ARMEB__
2320         cpuctrl |= CPU_CONTROL_BEND_ENABLE;
2321 #endif
2322
2323         /* Clear out the cache */
2324         cpu_idcache_wbinv_all();
2325
2326         /* Now really make sure they are clean.  */
2327         __asm __volatile ("mcr\tp15, 0, r0, c7, c7, 0" : : );
2328
2329         if (vector_page == ARM_VECTORS_HIGH)
2330                 cpuctrl |= CPU_CONTROL_VECRELOC;
2331
2332         /* Set the control register */
2333         ctrl = cpuctrl;
2334         cpu_control(0xffffffff, cpuctrl);
2335
2336         /* And again. */
2337         cpu_idcache_wbinv_all();
2338 }
2339 #endif  /* CPU_ARM9E || CPU_ARM10 */
2340
2341 #if defined(CPU_ARM1136) || defined(CPU_ARM1176)
2342 struct cpu_option arm11_options[] = {
2343         { "cpu.cache",          BIC, OR,  (CPU_CONTROL_IC_ENABLE | CPU_CONTROL_DC_ENABLE) },
2344         { "cpu.nocache",        OR,  BIC, (CPU_CONTROL_IC_ENABLE | CPU_CONTROL_DC_ENABLE) },
2345         { "arm11.cache",        BIC, OR,  (CPU_CONTROL_IC_ENABLE | CPU_CONTROL_DC_ENABLE) },
2346         { "arm11.icache",       BIC, OR,  CPU_CONTROL_IC_ENABLE },
2347         { "arm11.dcache",       BIC, OR,  CPU_CONTROL_DC_ENABLE },
2348         { NULL,                 IGN, IGN, 0 }
2349 };
2350
2351 void
2352 arm11x6_setup(char *args)
2353 {
2354         int cpuctrl, cpuctrl_wax;
2355         uint32_t auxctrl, auxctrl_wax;
2356         uint32_t tmp, tmp2;
2357         uint32_t sbz=0;
2358         uint32_t cpuid;
2359
2360         cpuid = cpufunc_id();
2361
2362         cpuctrl =
2363                 CPU_CONTROL_MMU_ENABLE  |
2364                 CPU_CONTROL_DC_ENABLE   |
2365                 CPU_CONTROL_WBUF_ENABLE |
2366                 CPU_CONTROL_32BP_ENABLE |
2367                 CPU_CONTROL_32BD_ENABLE |
2368                 CPU_CONTROL_LABT_ENABLE |
2369                 CPU_CONTROL_SYST_ENABLE |
2370                 CPU_CONTROL_IC_ENABLE;
2371
2372         /*
2373          * "write as existing" bits
2374          * inverse of this is mask
2375          */
2376         cpuctrl_wax =
2377                 (3 << 30) | /* SBZ */
2378                 (1 << 29) | /* FA */
2379                 (1 << 28) | /* TR */
2380                 (3 << 26) | /* SBZ */ 
2381                 (3 << 19) | /* SBZ */
2382                 (1 << 17);  /* SBZ */
2383
2384         cpuctrl |= CPU_CONTROL_BPRD_ENABLE;
2385         cpuctrl |= CPU_CONTROL_V6_EXTPAGE;
2386
2387         cpuctrl = parse_cpu_options(args, arm11_options, cpuctrl);
2388
2389 #ifdef __ARMEB__
2390         cpuctrl |= CPU_CONTROL_BEND_ENABLE;
2391 #endif
2392
2393         if (vector_page == ARM_VECTORS_HIGH)
2394                 cpuctrl |= CPU_CONTROL_VECRELOC;
2395
2396         auxctrl = 0;
2397         auxctrl_wax = ~0;
2398         /*
2399          * This options enables the workaround for the 364296 ARM1136
2400          * r0pX errata (possible cache data corruption with
2401          * hit-under-miss enabled). It sets the undocumented bit 31 in
2402          * the auxiliary control register and the FI bit in the control
2403          * register, thus disabling hit-under-miss without putting the
2404          * processor into full low interrupt latency mode. ARM11MPCore
2405          * is not affected.
2406          */
2407         if ((cpuid & CPU_ID_CPU_MASK) == CPU_ID_ARM1136JS) { /* ARM1136JSr0pX */
2408                 cpuctrl |= CPU_CONTROL_FI_ENABLE;
2409                 auxctrl = ARM1136_AUXCTL_PFI;
2410                 auxctrl_wax = ~ARM1136_AUXCTL_PFI;
2411         }
2412
2413         /*
2414          * Enable an errata workaround
2415          */
2416         if ((cpuid & CPU_ID_CPU_MASK) == CPU_ID_ARM1176JZS) { /* ARM1176JZSr0 */
2417                 auxctrl = ARM1176_AUXCTL_PHD;
2418                 auxctrl_wax = ~ARM1176_AUXCTL_PHD;
2419         }
2420
2421         /* Clear out the cache */
2422         cpu_idcache_wbinv_all();
2423
2424         /* Now really make sure they are clean.  */
2425         __asm volatile ("mcr\tp15, 0, %0, c7, c7, 0" : : "r"(sbz));
2426
2427         /* Allow detection code to find the VFP if it's fitted.  */
2428         __asm volatile ("mcr\tp15, 0, %0, c1, c0, 2" : : "r" (0x0fffffff));
2429
2430         /* Set the control register */
2431         ctrl = cpuctrl;
2432         cpu_control(~cpuctrl_wax, cpuctrl);
2433
2434         __asm volatile ("mrc    p15, 0, %0, c1, c0, 1\n\t"
2435                         "and    %1, %0, %2\n\t"
2436                         "orr    %1, %1, %3\n\t"
2437                         "teq    %0, %1\n\t"
2438                         "mcrne  p15, 0, %1, c1, c0, 1\n\t"
2439                         : "=r"(tmp), "=r"(tmp2) :
2440                           "r"(auxctrl_wax), "r"(auxctrl));
2441
2442         /* And again. */
2443         cpu_idcache_wbinv_all();
2444 }
2445 #endif  /* CPU_ARM1136 || CPU_ARM1176 */
2446
2447 #ifdef CPU_MV_PJ4B
2448 void
2449 pj4bv6_setup(char *args)
2450 {
2451         int cpuctrl;
2452
2453         pj4b_config();
2454
2455         cpuctrl = CPU_CONTROL_MMU_ENABLE;
2456 #ifndef ARM32_DISABLE_ALIGNMENT_FAULTS
2457         cpuctrl |= CPU_CONTROL_AFLT_ENABLE;
2458 #endif
2459         cpuctrl |= CPU_CONTROL_DC_ENABLE;
2460         cpuctrl |= (0xf << 3);
2461 #ifdef __ARMEB__
2462         cpuctrl |= CPU_CONTROL_BEND_ENABLE;
2463 #endif
2464         cpuctrl |= CPU_CONTROL_SYST_ENABLE;
2465         cpuctrl |= CPU_CONTROL_BPRD_ENABLE;
2466         cpuctrl |= CPU_CONTROL_IC_ENABLE;
2467         if (vector_page == ARM_VECTORS_HIGH)
2468                 cpuctrl |= CPU_CONTROL_VECRELOC;
2469         cpuctrl |= (0x5 << 16);
2470         cpuctrl |= CPU_CONTROL_V6_EXTPAGE;
2471         /* XXX not yet */
2472         /* cpuctrl |= CPU_CONTROL_L2_ENABLE; */
2473
2474         /* Make sure caches are clean.  */
2475         cpu_idcache_wbinv_all();
2476         cpu_l2cache_wbinv_all();
2477
2478         /* Set the control register */
2479         ctrl = cpuctrl;
2480         cpu_control(0xffffffff, cpuctrl);
2481
2482         cpu_idcache_wbinv_all();
2483         cpu_l2cache_wbinv_all();
2484 }
2485
2486 void
2487 pj4bv7_setup(args)
2488         char *args;
2489 {
2490         int cpuctrl;
2491
2492         pj4b_config();
2493
2494         cpuctrl = CPU_CONTROL_MMU_ENABLE;
2495 #ifndef ARM32_DISABLE_ALIGNMENT_FAULTS
2496         cpuctrl |= CPU_CONTROL_AFLT_ENABLE;
2497 #endif
2498         cpuctrl |= CPU_CONTROL_DC_ENABLE;
2499         cpuctrl |= (0xf << 3);
2500         cpuctrl |= CPU_CONTROL_BPRD_ENABLE;
2501         cpuctrl |= CPU_CONTROL_IC_ENABLE;
2502         if (vector_page == ARM_VECTORS_HIGH)
2503                 cpuctrl |= CPU_CONTROL_VECRELOC;
2504         cpuctrl |= (0x5 << 16) | (1 < 22);
2505         cpuctrl |= CPU_CONTROL_V6_EXTPAGE;
2506
2507         /* Clear out the cache */
2508         cpu_idcache_wbinv_all();
2509
2510         /* Set the control register */
2511         ctrl = cpuctrl;
2512         cpu_control(0xFFFFFFFF, cpuctrl);
2513
2514         /* And again. */
2515         cpu_idcache_wbinv_all();
2516 }
2517 #endif /* CPU_MV_PJ4B */
2518
2519 #ifdef CPU_CORTEXA
2520
2521 void
2522 cortexa_setup(char *args)
2523 {
2524         int cpuctrl, cpuctrlmask;
2525         
2526         cpuctrlmask = CPU_CONTROL_MMU_ENABLE |     /* MMU enable         [0] */
2527             CPU_CONTROL_AFLT_ENABLE |    /* Alignment fault    [1] */
2528             CPU_CONTROL_DC_ENABLE |      /* DCache enable      [2] */
2529             CPU_CONTROL_BPRD_ENABLE |    /* Branch prediction [11] */
2530             CPU_CONTROL_IC_ENABLE |      /* ICache enable     [12] */
2531             CPU_CONTROL_VECRELOC;        /* Vector relocation [13] */
2532         
2533         cpuctrl = CPU_CONTROL_MMU_ENABLE |
2534             CPU_CONTROL_IC_ENABLE |
2535             CPU_CONTROL_DC_ENABLE |
2536             CPU_CONTROL_BPRD_ENABLE;
2537         
2538 #ifndef ARM32_DISABLE_ALIGNMENT_FAULTS
2539         cpuctrl |= CPU_CONTROL_AFLT_ENABLE;
2540 #endif
2541         
2542         /* Switch to big endian */
2543 #ifdef __ARMEB__
2544         cpuctrl |= CPU_CONTROL_BEND_ENABLE;
2545 #endif
2546         
2547         /* Check if the vector page is at the high address (0xffff0000) */
2548         if (vector_page == ARM_VECTORS_HIGH)
2549                 cpuctrl |= CPU_CONTROL_VECRELOC;
2550         
2551         /* Clear out the cache */
2552         cpu_idcache_wbinv_all();
2553         
2554         /* Set the control register */
2555         ctrl = cpuctrl;
2556         cpu_control(cpuctrlmask, cpuctrl);
2557         
2558         /* And again. */
2559         cpu_idcache_wbinv_all();
2560 #ifdef SMP
2561         armv7_auxctrl((1 << 6) | (1 << 0), (1 << 6) | (1 << 0)); /* Enable SMP + TLB broadcasting  */
2562 #endif
2563 }
2564 #endif  /* CPU_CORTEXA */
2565
2566
2567 #ifdef CPU_SA110
2568 struct cpu_option sa110_options[] = {
2569 #ifdef COMPAT_12
2570         { "nocache",            IGN, BIC, (CPU_CONTROL_IC_ENABLE | CPU_CONTROL_DC_ENABLE) },
2571         { "nowritebuf",         IGN, BIC, CPU_CONTROL_WBUF_ENABLE },
2572 #endif  /* COMPAT_12 */
2573         { "cpu.cache",          BIC, OR,  (CPU_CONTROL_IC_ENABLE | CPU_CONTROL_DC_ENABLE) },
2574         { "cpu.nocache",        OR,  BIC, (CPU_CONTROL_IC_ENABLE | CPU_CONTROL_DC_ENABLE) },
2575         { "sa110.cache",        BIC, OR,  (CPU_CONTROL_IC_ENABLE | CPU_CONTROL_DC_ENABLE) },
2576         { "sa110.icache",       BIC, OR,  CPU_CONTROL_IC_ENABLE },
2577         { "sa110.dcache",       BIC, OR,  CPU_CONTROL_DC_ENABLE },
2578         { "cpu.writebuf",       BIC, OR,  CPU_CONTROL_WBUF_ENABLE },
2579         { "cpu.nowritebuf",     OR,  BIC, CPU_CONTROL_WBUF_ENABLE },
2580         { "sa110.writebuf",     BIC, OR,  CPU_CONTROL_WBUF_ENABLE },
2581         { NULL,                 IGN, IGN, 0 }
2582 };
2583
2584 void
2585 sa110_setup(args)
2586         char *args;
2587 {
2588         int cpuctrl, cpuctrlmask;
2589
2590         cpuctrl = CPU_CONTROL_MMU_ENABLE | CPU_CONTROL_32BP_ENABLE
2591                  | CPU_CONTROL_32BD_ENABLE | CPU_CONTROL_SYST_ENABLE
2592                  | CPU_CONTROL_IC_ENABLE | CPU_CONTROL_DC_ENABLE
2593                  | CPU_CONTROL_WBUF_ENABLE;
2594         cpuctrlmask = CPU_CONTROL_MMU_ENABLE | CPU_CONTROL_32BP_ENABLE
2595                  | CPU_CONTROL_32BD_ENABLE | CPU_CONTROL_SYST_ENABLE
2596                  | CPU_CONTROL_IC_ENABLE | CPU_CONTROL_DC_ENABLE
2597                  | CPU_CONTROL_WBUF_ENABLE | CPU_CONTROL_ROM_ENABLE
2598                  | CPU_CONTROL_BEND_ENABLE | CPU_CONTROL_AFLT_ENABLE
2599                  | CPU_CONTROL_LABT_ENABLE | CPU_CONTROL_BPRD_ENABLE
2600                  | CPU_CONTROL_CPCLK;
2601
2602 #ifndef ARM32_DISABLE_ALIGNMENT_FAULTS
2603         cpuctrl |= CPU_CONTROL_AFLT_ENABLE;
2604 #endif
2605
2606         cpuctrl = parse_cpu_options(args, sa110_options, cpuctrl);
2607
2608 #ifdef __ARMEB__
2609         cpuctrl |= CPU_CONTROL_BEND_ENABLE;
2610 #endif
2611
2612         /* Clear out the cache */
2613         cpu_idcache_wbinv_all();
2614
2615         /* Set the control register */
2616         ctrl = cpuctrl;
2617 /*      cpu_control(cpuctrlmask, cpuctrl);*/
2618         cpu_control(0xffffffff, cpuctrl);
2619
2620         /*
2621          * enable clockswitching, note that this doesn't read or write to r0,
2622          * r0 is just to make it valid asm
2623          */
2624         __asm ("mcr 15, 0, r0, c15, c1, 2");
2625 }
2626 #endif  /* CPU_SA110 */
2627
2628 #if defined(CPU_SA1100) || defined(CPU_SA1110)
2629 struct cpu_option sa11x0_options[] = {
2630 #ifdef COMPAT_12
2631         { "nocache",            IGN, BIC, (CPU_CONTROL_IC_ENABLE | CPU_CONTROL_DC_ENABLE) },
2632         { "nowritebuf",         IGN, BIC, CPU_CONTROL_WBUF_ENABLE },
2633 #endif  /* COMPAT_12 */
2634         { "cpu.cache",          BIC, OR,  (CPU_CONTROL_IC_ENABLE | CPU_CONTROL_DC_ENABLE) },
2635         { "cpu.nocache",        OR,  BIC, (CPU_CONTROL_IC_ENABLE | CPU_CONTROL_DC_ENABLE) },
2636         { "sa11x0.cache",       BIC, OR,  (CPU_CONTROL_IC_ENABLE | CPU_CONTROL_DC_ENABLE) },
2637         { "sa11x0.icache",      BIC, OR,  CPU_CONTROL_IC_ENABLE },
2638         { "sa11x0.dcache",      BIC, OR,  CPU_CONTROL_DC_ENABLE },
2639         { "cpu.writebuf",       BIC, OR,  CPU_CONTROL_WBUF_ENABLE },
2640         { "cpu.nowritebuf",     OR,  BIC, CPU_CONTROL_WBUF_ENABLE },
2641         { "sa11x0.writebuf",    BIC, OR,  CPU_CONTROL_WBUF_ENABLE },
2642         { NULL,                 IGN, IGN, 0 }
2643 };
2644
2645 void
2646 sa11x0_setup(args)
2647         char *args;
2648 {
2649         int cpuctrl, cpuctrlmask;
2650
2651         cpuctrl = CPU_CONTROL_MMU_ENABLE | CPU_CONTROL_32BP_ENABLE
2652                  | CPU_CONTROL_32BD_ENABLE | CPU_CONTROL_SYST_ENABLE
2653                  | CPU_CONTROL_IC_ENABLE | CPU_CONTROL_DC_ENABLE
2654                  | CPU_CONTROL_WBUF_ENABLE | CPU_CONTROL_LABT_ENABLE;
2655         cpuctrlmask = CPU_CONTROL_MMU_ENABLE | CPU_CONTROL_32BP_ENABLE
2656                  | CPU_CONTROL_32BD_ENABLE | CPU_CONTROL_SYST_ENABLE
2657                  | CPU_CONTROL_IC_ENABLE | CPU_CONTROL_DC_ENABLE
2658                  | CPU_CONTROL_WBUF_ENABLE | CPU_CONTROL_ROM_ENABLE
2659                  | CPU_CONTROL_BEND_ENABLE | CPU_CONTROL_AFLT_ENABLE
2660                  | CPU_CONTROL_LABT_ENABLE | CPU_CONTROL_BPRD_ENABLE
2661                  | CPU_CONTROL_CPCLK | CPU_CONTROL_VECRELOC;
2662
2663 #ifndef ARM32_DISABLE_ALIGNMENT_FAULTS
2664         cpuctrl |= CPU_CONTROL_AFLT_ENABLE;
2665 #endif
2666
2667
2668         cpuctrl = parse_cpu_options(args, sa11x0_options, cpuctrl);
2669
2670 #ifdef __ARMEB__
2671         cpuctrl |= CPU_CONTROL_BEND_ENABLE;
2672 #endif
2673
2674         if (vector_page == ARM_VECTORS_HIGH)
2675                 cpuctrl |= CPU_CONTROL_VECRELOC;
2676         /* Clear out the cache */
2677         cpu_idcache_wbinv_all();
2678         /* Set the control register */
2679         ctrl = cpuctrl;
2680         cpu_control(0xffffffff, cpuctrl);
2681 }
2682 #endif  /* CPU_SA1100 || CPU_SA1110 */
2683
2684 #if defined(CPU_FA526) || defined(CPU_FA626TE)
2685 struct cpu_option fa526_options[] = {
2686 #ifdef COMPAT_12
2687         { "nocache",            IGN, BIC, (CPU_CONTROL_IC_ENABLE |
2688                                            CPU_CONTROL_DC_ENABLE) },
2689         { "nowritebuf",         IGN, BIC, CPU_CONTROL_WBUF_ENABLE },
2690 #endif  /* COMPAT_12 */
2691         { "cpu.cache",          BIC, OR,  (CPU_CONTROL_IC_ENABLE |
2692                                            CPU_CONTROL_DC_ENABLE) },
2693         { "cpu.nocache",        OR,  BIC, (CPU_CONTROL_IC_ENABLE |
2694                                            CPU_CONTROL_DC_ENABLE) },
2695         { "cpu.writebuf",       BIC, OR,  CPU_CONTROL_WBUF_ENABLE },
2696         { "cpu.nowritebuf",     OR,  BIC, CPU_CONTROL_WBUF_ENABLE },
2697         { NULL,                 IGN, IGN, 0 }
2698 };
2699
2700 void
2701 fa526_setup(char *args)
2702 {
2703         int cpuctrl, cpuctrlmask;
2704
2705         cpuctrl = CPU_CONTROL_MMU_ENABLE | CPU_CONTROL_32BP_ENABLE
2706                  | CPU_CONTROL_32BD_ENABLE | CPU_CONTROL_SYST_ENABLE
2707                  | CPU_CONTROL_IC_ENABLE | CPU_CONTROL_DC_ENABLE
2708                  | CPU_CONTROL_WBUF_ENABLE | CPU_CONTROL_LABT_ENABLE
2709                 | CPU_CONTROL_BPRD_ENABLE;
2710         cpuctrlmask = CPU_CONTROL_MMU_ENABLE | CPU_CONTROL_32BP_ENABLE
2711                  | CPU_CONTROL_32BD_ENABLE | CPU_CONTROL_SYST_ENABLE
2712                  | CPU_CONTROL_IC_ENABLE | CPU_CONTROL_DC_ENABLE
2713                  | CPU_CONTROL_WBUF_ENABLE | CPU_CONTROL_ROM_ENABLE
2714                  | CPU_CONTROL_BEND_ENABLE | CPU_CONTROL_AFLT_ENABLE
2715                  | CPU_CONTROL_LABT_ENABLE | CPU_CONTROL_BPRD_ENABLE
2716                  | CPU_CONTROL_CPCLK | CPU_CONTROL_VECRELOC;
2717
2718 #ifndef ARM32_DISABLE_ALIGNMENT_FAULTS
2719         cpuctrl |= CPU_CONTROL_AFLT_ENABLE;
2720 #endif
2721
2722         cpuctrl = parse_cpu_options(args, fa526_options, cpuctrl);
2723
2724 #ifdef __ARMEB__
2725         cpuctrl |= CPU_CONTROL_BEND_ENABLE;
2726 #endif
2727
2728         if (vector_page == ARM_VECTORS_HIGH)
2729                 cpuctrl |= CPU_CONTROL_VECRELOC;
2730
2731         /* Clear out the cache */
2732         cpu_idcache_wbinv_all();
2733
2734         /* Set the control register */
2735         ctrl = cpuctrl;
2736         cpu_control(0xffffffff, cpuctrl);
2737 }
2738 #endif  /* CPU_FA526 || CPU_FA626TE */
2739
2740
2741 #if defined(CPU_IXP12X0)
2742 struct cpu_option ixp12x0_options[] = {
2743         { "cpu.cache",          BIC, OR,  (CPU_CONTROL_IC_ENABLE | CPU_CONTROL_DC_ENABLE) },
2744         { "cpu.nocache",        OR,  BIC, (CPU_CONTROL_IC_ENABLE | CPU_CONTROL_DC_ENABLE) },
2745         { "ixp12x0.cache",      BIC, OR,  (CPU_CONTROL_IC_ENABLE | CPU_CONTROL_DC_ENABLE) },
2746         { "ixp12x0.icache",     BIC, OR,  CPU_CONTROL_IC_ENABLE },
2747         { "ixp12x0.dcache",     BIC, OR,  CPU_CONTROL_DC_ENABLE },
2748         { "cpu.writebuf",       BIC, OR,  CPU_CONTROL_WBUF_ENABLE },
2749         { "cpu.nowritebuf",     OR,  BIC, CPU_CONTROL_WBUF_ENABLE },
2750         { "ixp12x0.writebuf",   BIC, OR,  CPU_CONTROL_WBUF_ENABLE },
2751         { NULL,                 IGN, IGN, 0 }
2752 };
2753
2754 void
2755 ixp12x0_setup(args)
2756         char *args;
2757 {
2758         int cpuctrl, cpuctrlmask;
2759
2760
2761         cpuctrl = CPU_CONTROL_MMU_ENABLE | CPU_CONTROL_DC_ENABLE
2762                  | CPU_CONTROL_WBUF_ENABLE | CPU_CONTROL_SYST_ENABLE
2763                  | CPU_CONTROL_IC_ENABLE;
2764
2765         cpuctrlmask = CPU_CONTROL_MMU_ENABLE | CPU_CONTROL_AFLT_ENABLE
2766                  | CPU_CONTROL_DC_ENABLE | CPU_CONTROL_WBUF_ENABLE
2767                  | CPU_CONTROL_BEND_ENABLE | CPU_CONTROL_SYST_ENABLE
2768                  | CPU_CONTROL_ROM_ENABLE | CPU_CONTROL_IC_ENABLE
2769                  | CPU_CONTROL_VECRELOC;
2770
2771 #ifndef ARM32_DISABLE_ALIGNMENT_FAULTS
2772         cpuctrl |= CPU_CONTROL_AFLT_ENABLE;
2773 #endif
2774
2775         cpuctrl = parse_cpu_options(args, ixp12x0_options, cpuctrl);
2776
2777 #ifdef __ARMEB__
2778         cpuctrl |= CPU_CONTROL_BEND_ENABLE;
2779 #endif
2780
2781         if (vector_page == ARM_VECTORS_HIGH)
2782                 cpuctrl |= CPU_CONTROL_VECRELOC;
2783
2784         /* Clear out the cache */
2785         cpu_idcache_wbinv_all();
2786
2787         /* Set the control register */
2788         ctrl = cpuctrl;
2789         /* cpu_control(0xffffffff, cpuctrl); */
2790         cpu_control(cpuctrlmask, cpuctrl);
2791 }
2792 #endif /* CPU_IXP12X0 */
2793
2794 #if defined(CPU_XSCALE_80200) || defined(CPU_XSCALE_80321) || \
2795   defined(CPU_XSCALE_PXA2X0) || defined(CPU_XSCALE_IXP425) || \
2796   defined(CPU_XSCALE_80219) || defined(CPU_XSCALE_81342)
2797 struct cpu_option xscale_options[] = {
2798 #ifdef COMPAT_12
2799         { "branchpredict",      BIC, OR,  CPU_CONTROL_BPRD_ENABLE },
2800         { "nocache",            IGN, BIC, (CPU_CONTROL_IC_ENABLE | CPU_CONTROL_DC_ENABLE) },
2801 #endif  /* COMPAT_12 */
2802         { "cpu.branchpredict",  BIC, OR,  CPU_CONTROL_BPRD_ENABLE },
2803         { "cpu.cache",          BIC, OR,  (CPU_CONTROL_IC_ENABLE | CPU_CONTROL_DC_ENABLE) },
2804         { "cpu.nocache",        OR,  BIC, (CPU_CONTROL_IC_ENABLE | CPU_CONTROL_DC_ENABLE) },
2805         { "xscale.branchpredict", BIC, OR,  CPU_CONTROL_BPRD_ENABLE },
2806         { "xscale.cache",       BIC, OR,  (CPU_CONTROL_IC_ENABLE | CPU_CONTROL_DC_ENABLE) },
2807         { "xscale.icache",      BIC, OR,  CPU_CONTROL_IC_ENABLE },
2808         { "xscale.dcache",      BIC, OR,  CPU_CONTROL_DC_ENABLE },
2809         { NULL,                 IGN, IGN, 0 }
2810 };
2811
2812 void
2813 xscale_setup(args)
2814         char *args;
2815 {
2816         uint32_t auxctl;
2817         int cpuctrl, cpuctrlmask;
2818
2819         /*
2820          * The XScale Write Buffer is always enabled.  Our option
2821          * is to enable/disable coalescing.  Note that bits 6:3
2822          * must always be enabled.
2823          */
2824
2825         cpuctrl = CPU_CONTROL_MMU_ENABLE | CPU_CONTROL_32BP_ENABLE
2826                  | CPU_CONTROL_32BD_ENABLE | CPU_CONTROL_SYST_ENABLE
2827                  | CPU_CONTROL_IC_ENABLE | CPU_CONTROL_DC_ENABLE
2828                  | CPU_CONTROL_WBUF_ENABLE | CPU_CONTROL_LABT_ENABLE
2829                  | CPU_CONTROL_BPRD_ENABLE;
2830         cpuctrlmask = CPU_CONTROL_MMU_ENABLE | CPU_CONTROL_32BP_ENABLE
2831                  | CPU_CONTROL_32BD_ENABLE | CPU_CONTROL_SYST_ENABLE
2832                  | CPU_CONTROL_IC_ENABLE | CPU_CONTROL_DC_ENABLE
2833                  | CPU_CONTROL_WBUF_ENABLE | CPU_CONTROL_ROM_ENABLE
2834                  | CPU_CONTROL_BEND_ENABLE | CPU_CONTROL_AFLT_ENABLE
2835                  | CPU_CONTROL_LABT_ENABLE | CPU_CONTROL_BPRD_ENABLE
2836                  | CPU_CONTROL_CPCLK | CPU_CONTROL_VECRELOC | \
2837                  CPU_CONTROL_L2_ENABLE;
2838
2839 #ifndef ARM32_DISABLE_ALIGNMENT_FAULTS
2840         cpuctrl |= CPU_CONTROL_AFLT_ENABLE;
2841 #endif
2842
2843         cpuctrl = parse_cpu_options(args, xscale_options, cpuctrl);
2844
2845 #ifdef __ARMEB__
2846         cpuctrl |= CPU_CONTROL_BEND_ENABLE;
2847 #endif
2848
2849         if (vector_page == ARM_VECTORS_HIGH)
2850                 cpuctrl |= CPU_CONTROL_VECRELOC;
2851 #ifdef CPU_XSCALE_CORE3
2852         cpuctrl |= CPU_CONTROL_L2_ENABLE;
2853 #endif
2854
2855         /* Clear out the cache */
2856         cpu_idcache_wbinv_all();
2857
2858         /*
2859          * Set the control register.  Note that bits 6:3 must always
2860          * be set to 1.
2861          */
2862         ctrl = cpuctrl;
2863 /*      cpu_control(cpuctrlmask, cpuctrl);*/
2864         cpu_control(0xffffffff, cpuctrl);
2865
2866         /* Make sure write coalescing is turned on */
2867         __asm __volatile("mrc p15, 0, %0, c1, c0, 1"
2868                 : "=r" (auxctl));
2869 #ifdef XSCALE_NO_COALESCE_WRITES
2870         auxctl |= XSCALE_AUXCTL_K;
2871 #else
2872         auxctl &= ~XSCALE_AUXCTL_K;
2873 #endif
2874 #ifdef CPU_XSCALE_CORE3
2875         auxctl |= XSCALE_AUXCTL_LLR;
2876         auxctl |= XSCALE_AUXCTL_MD_MASK;
2877 #endif
2878         __asm __volatile("mcr p15, 0, %0, c1, c0, 1"
2879                 : : "r" (auxctl));
2880 }
2881 #endif  /* CPU_XSCALE_80200 || CPU_XSCALE_80321 || CPU_XSCALE_PXA2X0 || CPU_XSCALE_IXP425
2882            CPU_XSCALE_80219 */