[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]

FreeBSD/Linux Kernel Cross Reference
sys/arm/arm/cpufunc.c

Version: -  FREEBSD  -  FREEBSD7  -  FREEBSD71  -  FREEBSD70  -  FREEBSD6  -  FREEBSD64  -  FREEBSD63  -  FREEBSD62  -  FREEBSD61  -  FREEBSD60  -  FREEBSD5  -  FREEBSD55  -  FREEBSD54  -  FREEBSD53  -  FREEBSD52  -  FREEBSD51  -  FREEBSD50  -  FREEBSD4  -  FREEBSD3  -  FREEBSD22  -  linux-2.6  -  linux-2.4.22  -  MK83  -  MK84  -  PLAN9  -  DFBSD  -  NETBSD  -  NETBSD5  -  NETBSD4  -  NETBSD3  -  NETBSD20  -  OPENBSD  -  xnu-517  -  xnu-792  -  xnu-792.6.70  -  xnu-1228  -  OPENSOLARIS  -  minix-3-1-1  -  TRUSTEDBSD-SEBSD  -  FREEBSD-LIBC  -  FREEBSD7-LIBC  -  FREEBSD6-LIBC  -  GLIBC27 
SearchContext: -  none  -  excerpts  -  bigexcerpts 

  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: src/sys/arm/arm/cpufunc.c,v 1.24 2008/12/20 03:26:09 sam Exp $");
 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 #if defined(CPU_XSCALE_81342)
 78 #include <arm/xscale/i8134x/i81342reg.h>
 79 #endif
 80 
 81 #ifdef CPU_XSCALE_IXP425
 82 #include <arm/xscale/ixp425/ixp425reg.h>
 83 #include <arm/xscale/ixp425/ixp425var.h>
 84 #endif
 85 
 86 #if defined(CPU_XSCALE_80200) || defined(CPU_XSCALE_80321) || \
 87     defined(CPU_XSCALE_80219) || defined(CPU_XSCALE_81342)
 88 #include <arm/xscale/xscalereg.h>
 89 #endif
 90 
 91 #if defined(PERFCTRS)
 92 struct arm_pmc_funcs *arm_pmc;
 93 #endif
 94 
 95 /* PRIMARY CACHE VARIABLES */
 96 int     arm_picache_size;
 97 int     arm_picache_line_size;
 98 int     arm_picache_ways;
 99 
100 int     arm_pdcache_size;       /* and unified */
101 int     arm_pdcache_line_size;
102 int     arm_pdcache_ways;
103 
104 int     arm_pcache_type;
105 int     arm_pcache_unified;
106 
107 int     arm_dcache_align;
108 int     arm_dcache_align_mask;
109 
110 /* 1 == use cpu_sleep(), 0 == don't */
111 int cpu_do_powersave;
112 int ctrl;
113 
114 #ifdef CPU_ARM7TDMI
115 struct cpu_functions arm7tdmi_cpufuncs = {
116         /* CPU functions */
117         
118         cpufunc_id,                     /* id                   */
119         cpufunc_nullop,                 /* cpwait               */
120 
121         /* MMU functions */
122 
123         cpufunc_control,                /* control              */
124         cpufunc_domains,                /* domain               */
125         arm7tdmi_setttb,                /* setttb               */
126         cpufunc_faultstatus,            /* faultstatus          */
127         cpufunc_faultaddress,           /* faultaddress         */
128 
129         /* TLB functions */
130 
131         arm7tdmi_tlb_flushID,           /* tlb_flushID          */
132         arm7tdmi_tlb_flushID_SE,        /* tlb_flushID_SE       */
133         arm7tdmi_tlb_flushID,           /* tlb_flushI           */
134         arm7tdmi_tlb_flushID_SE,        /* tlb_flushI_SE        */
135         arm7tdmi_tlb_flushID,           /* tlb_flushD           */
136         arm7tdmi_tlb_flushID_SE,        /* tlb_flushD_SE        */
137 
138         /* Cache operations */
139 
140         cpufunc_nullop,                 /* icache_sync_all      */
141         (void *)cpufunc_nullop,         /* icache_sync_range    */
142 
143         arm7tdmi_cache_flushID,         /* dcache_wbinv_all     */
144         (void *)arm7tdmi_cache_flushID, /* dcache_wbinv_range   */
145         (void *)arm7tdmi_cache_flushID, /* dcache_inv_range     */
146         (void *)cpufunc_nullop,         /* dcache_wb_range      */
147 
148         arm7tdmi_cache_flushID,         /* idcache_wbinv_all    */
149         (void *)arm7tdmi_cache_flushID, /* idcache_wbinv_range  */
150         cpufunc_nullop,                 /* l2cache_wbinv_all    */
151         (void *)cpufunc_nullop,         /* l2cache_wbinv_range  */
152         (void *)cpufunc_nullop,         /* l2cache_inv_range    */
153         (void *)cpufunc_nullop,         /* l2cache_wb_range     */
154 
155         /* Other functions */
156 
157         cpufunc_nullop,                 /* flush_prefetchbuf    */
158         cpufunc_nullop,                 /* drain_writebuf       */
159         cpufunc_nullop,                 /* flush_brnchtgt_C     */
160         (void *)cpufunc_nullop,         /* flush_brnchtgt_E     */
161 
162         (void *)cpufunc_nullop,         /* sleep                */
163 
164         /* Soft functions */
165 
166         late_abort_fixup,               /* dataabt_fixup        */
167         cpufunc_null_fixup,             /* prefetchabt_fixup    */
168 
169         arm7tdmi_context_switch,        /* context_switch       */
170 
171         arm7tdmi_setup                  /* cpu setup            */
172 
173 };
174 #endif  /* CPU_ARM7TDMI */
175 
176 #ifdef CPU_ARM8
177 struct cpu_functions arm8_cpufuncs = {
178         /* CPU functions */
179         
180         cpufunc_id,                     /* id                   */
181         cpufunc_nullop,                 /* cpwait               */
182 
183         /* MMU functions */
184 
185         cpufunc_control,                /* control              */
186         cpufunc_domains,                /* domain               */
187         arm8_setttb,                    /* setttb               */
188         cpufunc_faultstatus,            /* faultstatus          */
189         cpufunc_faultaddress,           /* faultaddress         */
190 
191         /* TLB functions */
192 
193         arm8_tlb_flushID,               /* tlb_flushID          */
194         arm8_tlb_flushID_SE,            /* tlb_flushID_SE       */
195         arm8_tlb_flushID,               /* tlb_flushI           */
196         arm8_tlb_flushID_SE,            /* tlb_flushI_SE        */
197         arm8_tlb_flushID,               /* tlb_flushD           */
198         arm8_tlb_flushID_SE,            /* tlb_flushD_SE        */
199 
200         /* Cache operations */
201 
202         cpufunc_nullop,                 /* icache_sync_all      */
203         (void *)cpufunc_nullop,         /* icache_sync_range    */
204 
205         arm8_cache_purgeID,             /* dcache_wbinv_all     */
206         (void *)arm8_cache_purgeID,     /* dcache_wbinv_range   */
207 /*XXX*/ (void *)arm8_cache_purgeID,     /* dcache_inv_range     */
208         (void *)arm8_cache_cleanID,     /* dcache_wb_range      */
209 
210         arm8_cache_purgeID,             /* idcache_wbinv_all    */
211         (void *)arm8_cache_purgeID,     /* idcache_wbinv_range  */
212         cpufunc_nullop,                 /* l2cache_wbinv_all    */
213         (void *)cpufunc_nullop,         /* l2cache_wbinv_range  */
214         (void *)cpufunc_nullop,         /* l2cache_inv_range    */
215         (void *)cpufunc_nullop,         /* l2cache_wb_range     */
216 
217         /* Other functions */
218 
219         cpufunc_nullop,                 /* flush_prefetchbuf    */
220         cpufunc_nullop,                 /* drain_writebuf       */
221         cpufunc_nullop,                 /* flush_brnchtgt_C     */
222         (void *)cpufunc_nullop,         /* flush_brnchtgt_E     */
223 
224         (void *)cpufunc_nullop,         /* sleep                */
225 
226         /* Soft functions */
227 
228         cpufunc_null_fixup,             /* dataabt_fixup        */
229         cpufunc_null_fixup,             /* prefetchabt_fixup    */
230 
231         arm8_context_switch,            /* context_switch       */
232 
233         arm8_setup                      /* cpu setup            */
234 };          
235 #endif  /* CPU_ARM8 */
236 
237 #ifdef CPU_ARM9
238 struct cpu_functions arm9_cpufuncs = {
239         /* CPU functions */
240 
241         cpufunc_id,                     /* id                   */
242         cpufunc_nullop,                 /* cpwait               */
243 
244         /* MMU functions */
245 
246         cpufunc_control,                /* control              */
247         cpufunc_domains,                /* Domain               */
248         arm9_setttb,                    /* Setttb               */
249         cpufunc_faultstatus,            /* Faultstatus          */
250         cpufunc_faultaddress,           /* Faultaddress         */
251 
252         /* TLB functions */
253 
254         armv4_tlb_flushID,              /* tlb_flushID          */
255         arm9_tlb_flushID_SE,            /* tlb_flushID_SE       */
256         armv4_tlb_flushI,               /* tlb_flushI           */
257         (void *)armv4_tlb_flushI,       /* tlb_flushI_SE        */
258         armv4_tlb_flushD,               /* tlb_flushD           */
259         armv4_tlb_flushD_SE,            /* tlb_flushD_SE        */
260 
261         /* Cache operations */
262 
263         arm9_icache_sync_all,           /* icache_sync_all      */
264         arm9_icache_sync_range,         /* icache_sync_range    */
265 
266         arm9_dcache_wbinv_all,          /* dcache_wbinv_all     */
267         arm9_dcache_wbinv_range,        /* dcache_wbinv_range   */
268 /*XXX*/ arm9_dcache_wbinv_range,        /* dcache_inv_range     */
269         arm9_dcache_wb_range,           /* dcache_wb_range      */
270 
271         arm9_idcache_wbinv_all,         /* idcache_wbinv_all    */
272         arm9_idcache_wbinv_range,       /* idcache_wbinv_range  */
273         cpufunc_nullop,                 /* l2cache_wbinv_all    */
274         (void *)cpufunc_nullop,         /* l2cache_wbinv_range  */
275         (void *)cpufunc_nullop,         /* l2cache_inv_range    */
276         (void *)cpufunc_nullop,         /* l2cache_wb_range     */
277 
278         /* Other functions */
279 
280         cpufunc_nullop,                 /* flush_prefetchbuf    */
281         armv4_drain_writebuf,           /* drain_writebuf       */
282         cpufunc_nullop,                 /* flush_brnchtgt_C     */
283         (void *)cpufunc_nullop,         /* flush_brnchtgt_E     */
284 
285         (void *)cpufunc_nullop,         /* sleep                */
286 
287         /* Soft functions */
288 
289         cpufunc_null_fixup,             /* dataabt_fixup        */
290         cpufunc_null_fixup,             /* prefetchabt_fixup    */
291 
292         arm9_context_switch,            /* context_switch       */
293 
294         arm9_setup                      /* cpu setup            */
295 
296 };
297 #endif /* CPU_ARM9 */
298 
299 #if defined(CPU_ARM9E) || defined(CPU_ARM10)
300 struct cpu_functions armv5_ec_cpufuncs = {
301         /* CPU functions */
302 
303         cpufunc_id,                     /* id                   */
304         cpufunc_nullop,                 /* cpwait               */
305 
306         /* MMU functions */
307 
308         cpufunc_control,                /* control              */
309         cpufunc_domains,                /* Domain               */
310         armv5_ec_setttb,                /* Setttb               */
311         cpufunc_faultstatus,            /* Faultstatus          */
312         cpufunc_faultaddress,           /* Faultaddress         */
313 
314         /* TLB functions */
315 
316         armv4_tlb_flushID,              /* tlb_flushID          */
317         arm10_tlb_flushID_SE,           /* tlb_flushID_SE       */
318         armv4_tlb_flushI,               /* tlb_flushI           */
319         arm10_tlb_flushI_SE,            /* tlb_flushI_SE        */
320         armv4_tlb_flushD,               /* tlb_flushD           */
321         armv4_tlb_flushD_SE,            /* tlb_flushD_SE        */
322 
323         /* Cache operations */
324 
325         armv5_ec_icache_sync_all,       /* icache_sync_all      */
326         armv5_ec_icache_sync_range,     /* icache_sync_range    */
327 
328         armv5_ec_dcache_wbinv_all,      /* dcache_wbinv_all     */
329         armv5_ec_dcache_wbinv_range,    /* dcache_wbinv_range   */
330 /*XXX*/ armv5_ec_dcache_wbinv_range,    /* dcache_inv_range     */
331         armv5_ec_dcache_wb_range,       /* dcache_wb_range      */
332 
333         armv5_ec_idcache_wbinv_all,     /* idcache_wbinv_all    */
334         armv5_ec_idcache_wbinv_range,   /* idcache_wbinv_range  */
335 
336         cpufunc_nullop,                 /* l2cache_wbinv_all    */
337         (void *)cpufunc_nullop,         /* l2cache_wbinv_range  */
338         (void *)cpufunc_nullop,         /* l2cache_inv_range    */
339         (void *)cpufunc_nullop,         /* l2cache_wb_range     */
340                                  
341         /* Other functions */
342 
343         cpufunc_nullop,                 /* flush_prefetchbuf    */
344         armv4_drain_writebuf,           /* drain_writebuf       */
345         cpufunc_nullop,                 /* flush_brnchtgt_C     */
346         (void *)cpufunc_nullop,         /* flush_brnchtgt_E     */
347 
348         (void *)cpufunc_nullop,         /* sleep                */
349 
350         /* Soft functions */
351 
352         cpufunc_null_fixup,             /* dataabt_fixup        */
353         cpufunc_null_fixup,             /* prefetchabt_fixup    */
354 
355         arm10_context_switch,           /* context_switch       */
356 
357         arm10_setup                     /* cpu setup            */
358 
359 };
360 
361 struct cpu_functions feroceon_cpufuncs = {
362         /* CPU functions */
363 
364         cpufunc_id,                     /* id                   */
365         cpufunc_nullop,                 /* cpwait               */
366 
367         /* MMU functions */
368 
369         cpufunc_control,                /* control              */
370         cpufunc_domains,                /* Domain               */
371         feroceon_setttb,                /* Setttb               */
372         cpufunc_faultstatus,            /* Faultstatus          */
373         cpufunc_faultaddress,           /* Faultaddress         */
374 
375         /* TLB functions */
376 
377         armv4_tlb_flushID,              /* tlb_flushID          */
378         arm10_tlb_flushID_SE,           /* tlb_flushID_SE       */
379         armv4_tlb_flushI,               /* tlb_flushI           */
380         arm10_tlb_flushI_SE,            /* tlb_flushI_SE        */
381         armv4_tlb_flushD,               /* tlb_flushD           */
382         armv4_tlb_flushD_SE,            /* tlb_flushD_SE        */
383 
384         /* Cache operations */
385 
386         armv5_ec_icache_sync_all,       /* icache_sync_all      */
387         armv5_ec_icache_sync_range,     /* icache_sync_range    */
388 
389         armv5_ec_dcache_wbinv_all,      /* dcache_wbinv_all     */
390         feroceon_dcache_wbinv_range,    /* dcache_wbinv_range   */
391         feroceon_dcache_inv_range,      /* dcache_inv_range     */
392         feroceon_dcache_wb_range,       /* dcache_wb_range      */
393 
394         armv5_ec_idcache_wbinv_all,     /* idcache_wbinv_all    */
395         feroceon_idcache_wbinv_range,   /* idcache_wbinv_all    */
396 
397         feroceon_l2cache_wbinv_all,     /* l2cache_wbinv_all    */
398         feroceon_l2cache_wbinv_range,   /* l2cache_wbinv_range  */
399         feroceon_l2cache_inv_range,     /* l2cache_inv_range    */
400         feroceon_l2cache_wb_range,      /* l2cache_wb_range     */
401 
402         /* Other functions */
403 
404         cpufunc_nullop,                 /* flush_prefetchbuf    */
405         armv4_drain_writebuf,           /* drain_writebuf       */
406         cpufunc_nullop,                 /* flush_brnchtgt_C     */
407         (void *)cpufunc_nullop,         /* flush_brnchtgt_E     */
408 
409         (void *)cpufunc_nullop,         /* sleep                */
410 
411         /* Soft functions */
412 
413         cpufunc_null_fixup,             /* dataabt_fixup        */
414         cpufunc_null_fixup,             /* prefetchabt_fixup    */
415 
416         arm10_context_switch,           /* context_switch       */
417 
418         arm10_setup                     /* cpu setup            */
419 };
420 #endif /* CPU_ARM9E || CPU_ARM10 */
421 
422 #ifdef CPU_ARM10
423 struct cpu_functions arm10_cpufuncs = {
424         /* CPU functions */
425 
426         cpufunc_id,                     /* id                   */
427         cpufunc_nullop,                 /* cpwait               */
428 
429         /* MMU functions */
430 
431         cpufunc_control,                /* control              */
432         cpufunc_domains,                /* Domain               */
433         arm10_setttb,                   /* Setttb               */
434         cpufunc_faultstatus,            /* Faultstatus          */
435         cpufunc_faultaddress,           /* Faultaddress         */
436 
437         /* TLB functions */
438 
439         armv4_tlb_flushID,              /* tlb_flushID          */
440         arm10_tlb_flushID_SE,           /* tlb_flushID_SE       */
441         armv4_tlb_flushI,               /* tlb_flushI           */
442         arm10_tlb_flushI_SE,            /* tlb_flushI_SE        */
443         armv4_tlb_flushD,               /* tlb_flushD           */
444         armv4_tlb_flushD_SE,            /* tlb_flushD_SE        */
445 
446         /* Cache operations */
447 
448         arm10_icache_sync_all,          /* icache_sync_all      */
449         arm10_icache_sync_range,        /* icache_sync_range    */
450 
451         arm10_dcache_wbinv_all,         /* dcache_wbinv_all     */
452         arm10_dcache_wbinv_range,       /* dcache_wbinv_range   */
453         arm10_dcache_inv_range,         /* dcache_inv_range     */
454         arm10_dcache_wb_range,          /* dcache_wb_range      */
455 
456         arm10_idcache_wbinv_all,        /* idcache_wbinv_all    */
457         arm10_idcache_wbinv_range,      /* idcache_wbinv_range  */
458         cpufunc_nullop,                 /* l2cache_wbinv_all    */
459         (void *)cpufunc_nullop,         /* l2cache_wbinv_range  */
460         (void *)cpufunc_nullop,         /* l2cache_inv_range    */
461         (void *)cpufunc_nullop,         /* l2cache_wb_range     */
462 
463         /* Other functions */
464 
465         cpufunc_nullop,                 /* flush_prefetchbuf    */
466         armv4_drain_writebuf,           /* drain_writebuf       */
467         cpufunc_nullop,                 /* flush_brnchtgt_C     */
468         (void *)cpufunc_nullop,         /* flush_brnchtgt_E     */
469 
470         (void *)cpufunc_nullop,         /* sleep                */
471 
472         /* Soft functions */
473 
474         cpufunc_null_fixup,             /* dataabt_fixup        */
475         cpufunc_null_fixup,             /* prefetchabt_fixup    */
476 
477         arm10_context_switch,           /* context_switch       */
478 
479         arm10_setup                     /* cpu setup            */
480 
481 };
482 #endif /* CPU_ARM10 */
483 
484 #ifdef CPU_SA110
485 struct cpu_functions sa110_cpufuncs = {
486         /* CPU functions */
487         
488         cpufunc_id,                     /* id                   */
489         cpufunc_nullop,                 /* cpwait               */
490 
491         /* MMU functions */
492 
493         cpufunc_control,                /* control              */
494         cpufunc_domains,                /* domain               */
495         sa1_setttb,                     /* setttb               */
496         cpufunc_faultstatus,            /* faultstatus          */
497         cpufunc_faultaddress,           /* faultaddress         */
498 
499         /* TLB functions */
500 
501         armv4_tlb_flushID,              /* tlb_flushID          */
502         sa1_tlb_flushID_SE,             /* tlb_flushID_SE       */
503         armv4_tlb_flushI,               /* tlb_flushI           */
504         (void *)armv4_tlb_flushI,       /* tlb_flushI_SE        */
505         armv4_tlb_flushD,               /* tlb_flushD           */
506         armv4_tlb_flushD_SE,            /* tlb_flushD_SE        */
507 
508         /* Cache operations */
509 
510         sa1_cache_syncI,                /* icache_sync_all      */
511         sa1_cache_syncI_rng,            /* icache_sync_range    */
512 
513         sa1_cache_purgeD,               /* dcache_wbinv_all     */
514         sa1_cache_purgeD_rng,           /* dcache_wbinv_range   */
515 /*XXX*/ sa1_cache_purgeD_rng,           /* dcache_inv_range     */
516         sa1_cache_cleanD_rng,           /* dcache_wb_range      */
517 
518         sa1_cache_purgeID,              /* idcache_wbinv_all    */
519         sa1_cache_purgeID_rng,          /* idcache_wbinv_range  */
520         cpufunc_nullop,                 /* l2cache_wbinv_all    */
521         (void *)cpufunc_nullop,         /* l2cache_wbinv_range  */
522         (void *)cpufunc_nullop,         /* l2cache_inv_range    */
523         (void *)cpufunc_nullop,         /* l2cache_wb_range     */
524 
525         /* Other functions */
526 
527         cpufunc_nullop,                 /* flush_prefetchbuf    */
528         armv4_drain_writebuf,           /* drain_writebuf       */
529         cpufunc_nullop,                 /* flush_brnchtgt_C     */
530         (void *)cpufunc_nullop,         /* flush_brnchtgt_E     */
531 
532         (void *)cpufunc_nullop,         /* sleep                */
533 
534         /* Soft functions */
535 
536         cpufunc_null_fixup,             /* dataabt_fixup        */
537         cpufunc_null_fixup,             /* prefetchabt_fixup    */
538 
539         sa110_context_switch,           /* context_switch       */
540 
541         sa110_setup                     /* cpu setup            */
542 };          
543 #endif  /* CPU_SA110 */
544 
545 #if defined(CPU_SA1100) || defined(CPU_SA1110)
546 struct cpu_functions sa11x0_cpufuncs = {
547         /* CPU functions */
548         
549         cpufunc_id,                     /* id                   */
550         cpufunc_nullop,                 /* cpwait               */
551 
552         /* MMU functions */
553 
554         cpufunc_control,                /* control              */
555         cpufunc_domains,                /* domain               */
556         sa1_setttb,                     /* setttb               */
557         cpufunc_faultstatus,            /* faultstatus          */
558         cpufunc_faultaddress,           /* faultaddress         */
559 
560         /* TLB functions */
561 
562         armv4_tlb_flushID,              /* tlb_flushID          */
563         sa1_tlb_flushID_SE,             /* tlb_flushID_SE       */
564         armv4_tlb_flushI,               /* tlb_flushI           */
565         (void *)armv4_tlb_flushI,       /* tlb_flushI_SE        */
566         armv4_tlb_flushD,               /* tlb_flushD           */
567         armv4_tlb_flushD_SE,            /* tlb_flushD_SE        */
568 
569         /* Cache operations */
570 
571         sa1_cache_syncI,                /* icache_sync_all      */
572         sa1_cache_syncI_rng,            /* icache_sync_range    */
573 
574         sa1_cache_purgeD,               /* dcache_wbinv_all     */
575         sa1_cache_purgeD_rng,           /* dcache_wbinv_range   */
576 /*XXX*/ sa1_cache_purgeD_rng,           /* dcache_inv_range     */
577         sa1_cache_cleanD_rng,           /* dcache_wb_range      */
578 
579         sa1_cache_purgeID,              /* idcache_wbinv_all    */
580         sa1_cache_purgeID_rng,          /* idcache_wbinv_range  */
581         cpufunc_nullop,                 /* l2cache_wbinv_all    */
582         (void *)cpufunc_nullop,         /* l2cache_wbinv_range  */
583         (void *)cpufunc_nullop,         /* l2cache_inv_range    */
584         (void *)cpufunc_nullop,         /* l2cache_wb_range     */
585 
586         /* Other functions */
587 
588         sa11x0_drain_readbuf,           /* flush_prefetchbuf    */
589         armv4_drain_writebuf,           /* drain_writebuf       */
590         cpufunc_nullop,                 /* flush_brnchtgt_C     */
591         (void *)cpufunc_nullop,         /* flush_brnchtgt_E     */
592 
593         sa11x0_cpu_sleep,               /* sleep                */
594 
595         /* Soft functions */
596 
597         cpufunc_null_fixup,             /* dataabt_fixup        */
598         cpufunc_null_fixup,             /* prefetchabt_fixup    */
599 
600         sa11x0_context_switch,          /* context_switch       */
601 
602         sa11x0_setup                    /* cpu setup            */
603 };          
604 #endif  /* CPU_SA1100 || CPU_SA1110 */
605 
606 #ifdef CPU_IXP12X0
607 struct cpu_functions ixp12x0_cpufuncs = {
608         /* CPU functions */
609         
610         cpufunc_id,                     /* id                   */
611         cpufunc_nullop,                 /* cpwait               */
612 
613         /* MMU functions */
614 
615         cpufunc_control,                /* control              */
616         cpufunc_domains,                /* domain               */
617         sa1_setttb,                     /* setttb               */
618         cpufunc_faultstatus,            /* faultstatus          */
619         cpufunc_faultaddress,           /* faultaddress         */
620 
621         /* TLB functions */
622 
623         armv4_tlb_flushID,              /* tlb_flushID          */
624         sa1_tlb_flushID_SE,             /* tlb_flushID_SE       */
625         armv4_tlb_flushI,               /* tlb_flushI           */
626         (void *)armv4_tlb_flushI,       /* tlb_flushI_SE        */
627         armv4_tlb_flushD,               /* tlb_flushD           */
628         armv4_tlb_flushD_SE,            /* tlb_flushD_SE        */
629 
630         /* Cache operations */
631 
632         sa1_cache_syncI,                /* icache_sync_all      */
633         sa1_cache_syncI_rng,            /* icache_sync_range    */
634 
635         sa1_cache_purgeD,               /* dcache_wbinv_all     */
636         sa1_cache_purgeD_rng,           /* dcache_wbinv_range   */
637 /*XXX*/ sa1_cache_purgeD_rng,           /* dcache_inv_range     */
638         sa1_cache_cleanD_rng,           /* dcache_wb_range      */
639 
640         sa1_cache_purgeID,              /* idcache_wbinv_all    */
641         sa1_cache_purgeID_rng,          /* idcache_wbinv_range  */
642         cpufunc_nullop,                 /* l2cache_wbinv_all    */
643         (void *)cpufunc_nullop,         /* l2cache_wbinv_range  */
644         (void *)cpufunc_nullop,         /* l2cache_inv_range    */
645         (void *)cpufunc_nullop,         /* l2cache_wb_range     */
646 
647         /* Other functions */
648 
649         ixp12x0_drain_readbuf,                  /* flush_prefetchbuf    */
650         armv4_drain_writebuf,           /* drain_writebuf       */
651         cpufunc_nullop,                 /* flush_brnchtgt_C     */
652         (void *)cpufunc_nullop,         /* flush_brnchtgt_E     */
653 
654         (void *)cpufunc_nullop,         /* sleep                */
655 
656         /* Soft functions */
657 
658         cpufunc_null_fixup,             /* dataabt_fixup        */
659         cpufunc_null_fixup,             /* prefetchabt_fixup    */
660 
661         ixp12x0_context_switch,         /* context_switch       */
662 
663         ixp12x0_setup                   /* cpu setup            */
664 };          
665 #endif  /* CPU_IXP12X0 */
666 
667 #if defined(CPU_XSCALE_80200) || defined(CPU_XSCALE_80321) || \
668   defined(CPU_XSCALE_PXA2X0) || defined(CPU_XSCALE_IXP425) || \
669   defined(CPU_XSCALE_80219)
670 
671 struct cpu_functions xscale_cpufuncs = {
672         /* CPU functions */
673         
674         cpufunc_id,                     /* id                   */
675         xscale_cpwait,                  /* cpwait               */
676 
677         /* MMU functions */
678 
679         xscale_control,                 /* control              */
680         cpufunc_domains,                /* domain               */
681         xscale_setttb,                  /* setttb               */
682         cpufunc_faultstatus,            /* faultstatus          */
683         cpufunc_faultaddress,           /* faultaddress         */
684 
685         /* TLB functions */
686 
687         armv4_tlb_flushID,              /* tlb_flushID          */
688         xscale_tlb_flushID_SE,          /* tlb_flushID_SE       */
689         armv4_tlb_flushI,               /* tlb_flushI           */
690         (void *)armv4_tlb_flushI,       /* tlb_flushI_SE        */
691         armv4_tlb_flushD,               /* tlb_flushD           */
692         armv4_tlb_flushD_SE,            /* tlb_flushD_SE        */
693 
694         /* Cache operations */
695 
696         xscale_cache_syncI,             /* icache_sync_all      */
697         xscale_cache_syncI_rng,         /* icache_sync_range    */
698 
699         xscale_cache_purgeD,            /* dcache_wbinv_all     */
700         xscale_cache_purgeD_rng,        /* dcache_wbinv_range   */
701         xscale_cache_flushD_rng,        /* dcache_inv_range     */
702         xscale_cache_cleanD_rng,        /* dcache_wb_range      */
703 
704         xscale_cache_purgeID,           /* idcache_wbinv_all    */
705         xscale_cache_purgeID_rng,       /* idcache_wbinv_range  */
706         cpufunc_nullop,                 /* l2cache_wbinv_all    */
707         (void *)cpufunc_nullop,         /* l2cache_wbinv_range  */
708         (void *)cpufunc_nullop,         /* l2cache_inv_range    */
709         (void *)cpufunc_nullop,         /* l2cache_wb_range     */
710 
711         /* Other functions */
712 
713         cpufunc_nullop,                 /* flush_prefetchbuf    */
714         armv4_drain_writebuf,           /* drain_writebuf       */
715         cpufunc_nullop,                 /* flush_brnchtgt_C     */
716         (void *)cpufunc_nullop,         /* flush_brnchtgt_E     */
717 
718         xscale_cpu_sleep,               /* sleep                */
719 
720         /* Soft functions */
721 
722         cpufunc_null_fixup,             /* dataabt_fixup        */
723         cpufunc_null_fixup,             /* prefetchabt_fixup    */
724 
725         xscale_context_switch,          /* context_switch       */
726 
727         xscale_setup                    /* cpu setup            */
728 };
729 #endif
730 /* CPU_XSCALE_80200 || CPU_XSCALE_80321 || CPU_XSCALE_PXA2X0 || CPU_XSCALE_IXP425
731    CPU_XSCALE_80219 */
732 
733 #ifdef CPU_XSCALE_81342
734 struct cpu_functions xscalec3_cpufuncs = {
735         /* CPU functions */
736         
737         cpufunc_id,                     /* id                   */
738         xscale_cpwait,                  /* cpwait               */
739 
740         /* MMU functions */
741 
742         xscale_control,                 /* control              */
743         cpufunc_domains,                /* domain               */
744         xscalec3_setttb,                /* setttb               */
745         cpufunc_faultstatus,            /* faultstatus          */
746         cpufunc_faultaddress,           /* faultaddress         */
747 
748         /* TLB functions */
749 
750         armv4_tlb_flushID,              /* tlb_flushID          */
751         xscale_tlb_flushID_SE,          /* tlb_flushID_SE       */
752         armv4_tlb_flushI,               /* tlb_flushI           */
753         (void *)armv4_tlb_flushI,       /* tlb_flushI_SE        */
754         armv4_tlb_flushD,               /* tlb_flushD           */
755         armv4_tlb_flushD_SE,            /* tlb_flushD_SE        */
756 
757         /* Cache operations */
758 
759         xscalec3_cache_syncI,           /* icache_sync_all      */
760         xscalec3_cache_syncI_rng,       /* icache_sync_range    */
761 
762         xscalec3_cache_purgeD,          /* dcache_wbinv_all     */
763         xscalec3_cache_purgeD_rng,      /* dcache_wbinv_range   */
764         xscale_cache_flushD_rng,        /* dcache_inv_range     */
765         xscalec3_cache_cleanD_rng,      /* dcache_wb_range      */
766 
767         xscalec3_cache_purgeID,         /* idcache_wbinv_all    */
768         xscalec3_cache_purgeID_rng,     /* idcache_wbinv_range  */
769         xscalec3_l2cache_purge,         /* l2cache_wbinv_all    */
770         xscalec3_l2cache_purge_rng,     /* l2cache_wbinv_range  */
771         xscalec3_l2cache_flush_rng,     /* l2cache_inv_range    */
772         xscalec3_l2cache_clean_rng,     /* l2cache_wb_range     */
773 
774         /* Other functions */
775 
776         cpufunc_nullop,                 /* flush_prefetchbuf    */
777         armv4_drain_writebuf,           /* drain_writebuf       */
778         cpufunc_nullop,                 /* flush_brnchtgt_C     */
779         (void *)cpufunc_nullop,         /* flush_brnchtgt_E     */
780 
781         xscale_cpu_sleep,               /* sleep                */
782 
783         /* Soft functions */
784 
785         cpufunc_null_fixup,             /* dataabt_fixup        */
786         cpufunc_null_fixup,             /* prefetchabt_fixup    */
787 
788         xscalec3_context_switch,        /* context_switch       */
789 
790         xscale_setup                    /* cpu setup            */
791 };
792 #endif /* CPU_XSCALE_81342 */
793 /*
794  * Global constants also used by locore.s
795  */
796 
797 struct cpu_functions cpufuncs;
798 u_int cputype;
799 u_int cpu_reset_needs_v4_MMU_disable;   /* flag used in locore.s */
800 
801 #if defined(CPU_ARM7TDMI) || defined(CPU_ARM8) || defined(CPU_ARM9) || \
802   defined (CPU_ARM9E) || defined (CPU_ARM10) ||                        \
803   defined(CPU_XSCALE_80200) || defined(CPU_XSCALE_80321) ||            \
804   defined(CPU_XSCALE_PXA2X0) || defined(CPU_XSCALE_IXP425) ||          \
805   defined(CPU_XSCALE_80219) || defined(CPU_XSCALE_81342)
806 
807 static void get_cachetype_cp15(void);
808 
809 /* Additional cache information local to this file.  Log2 of some of the
810    above numbers.  */
811 static int      arm_dcache_l2_nsets;
812 static int      arm_dcache_l2_assoc;
813 static int      arm_dcache_l2_linesize;
814 
815 static void
816 get_cachetype_cp15()
817 {
818         u_int ctype, isize, dsize;
819         u_int multiplier;
820 
821         __asm __volatile("mrc p15, 0, %0, c0, c0, 1"
822                 : "=r" (ctype));
823 
824         /*
825          * ...and thus spake the ARM ARM:
826          *
827          * If an <opcode2> value corresponding to an unimplemented or
828          * reserved ID register is encountered, the System Control
829          * processor returns the value of the main ID register.
830          */
831         if (ctype == cpufunc_id())
832                 goto out;
833 
834         if ((ctype & CPU_CT_S) == 0)
835                 arm_pcache_unified = 1;
836 
837         /*
838          * If you want to know how this code works, go read the ARM ARM.
839          */
840 
841         arm_pcache_type = CPU_CT_CTYPE(ctype);
842 
843         if (arm_pcache_unified == 0) {
844                 isize = CPU_CT_ISIZE(ctype);
845                 multiplier = (isize & CPU_CT_xSIZE_M) ? 3 : 2;
846                 arm_picache_line_size = 1U << (CPU_CT_xSIZE_LEN(isize) + 3);
847                 if (CPU_CT_xSIZE_ASSOC(isize) == 0) {
848                         if (isize & CPU_CT_xSIZE_M)
849                                 arm_picache_line_size = 0; /* not present */
850                         else
851                                 arm_picache_ways = 1;
852                 } else {
853                         arm_picache_ways = multiplier <<
854                             (CPU_CT_xSIZE_ASSOC(isize) - 1);
855                 }
856                 arm_picache_size = multiplier << (CPU_CT_xSIZE_SIZE(isize) + 8);
857         }
858 
859         dsize = CPU_CT_DSIZE(ctype);
860         multiplier = (dsize & CPU_CT_xSIZE_M) ? 3 : 2;
861         arm_pdcache_line_size = 1U << (CPU_CT_xSIZE_LEN(dsize) + 3);
862         if (CPU_CT_xSIZE_ASSOC(dsize) == 0) {
863                 if (dsize & CPU_CT_xSIZE_M)
864                         arm_pdcache_line_size = 0; /* not present */
865                 else
866                         arm_pdcache_ways = 1;
867         } else {
868                 arm_pdcache_ways = multiplier <<
869                     (CPU_CT_xSIZE_ASSOC(dsize) - 1);
870         }
871         arm_pdcache_size = multiplier << (CPU_CT_xSIZE_SIZE(dsize) + 8);
872 
873         arm_dcache_align = arm_pdcache_line_size;
874 
875         arm_dcache_l2_assoc = CPU_CT_xSIZE_ASSOC(dsize) + multiplier - 2;
876         arm_dcache_l2_linesize = CPU_CT_xSIZE_LEN(dsize) + 3;
877         arm_dcache_l2_nsets = 6 + CPU_CT_xSIZE_SIZE(dsize) -
878             CPU_CT_xSIZE_ASSOC(dsize) - CPU_CT_xSIZE_LEN(dsize);
879 
880  out:
881         arm_dcache_align_mask = arm_dcache_align - 1;
882 }
883 #endif /* ARM7TDMI || ARM8 || ARM9 || XSCALE */
884 
885 #if defined(CPU_SA110) || defined(CPU_SA1100) || defined(CPU_SA1110) || \
886     defined(CPU_IXP12X0)
887 /* Cache information for CPUs without cache type registers. */
888 struct cachetab {
889         u_int32_t ct_cpuid;
890         int     ct_pcache_type;
891         int     ct_pcache_unified;
892         int     ct_pdcache_size;
893         int     ct_pdcache_line_size;
894         int     ct_pdcache_ways;
895         int     ct_picache_size;
896         int     ct_picache_line_size;
897         int     ct_picache_ways;
898 };
899 
900 struct cachetab cachetab[] = {
901     /* cpuid,           cache type,       u,  dsiz, ls, wy,  isiz, ls, wy */
902     /* XXX is this type right for SA-1? */
903     { CPU_ID_SA110,     CPU_CT_CTYPE_WB1, 0, 16384, 32, 32, 16384, 32, 32 },
904     { CPU_ID_SA1100,    CPU_CT_CTYPE_WB1, 0,  8192, 32, 32, 16384, 32, 32 },
905     { CPU_ID_SA1110,    CPU_CT_CTYPE_WB1, 0,  8192, 32, 32, 16384, 32, 32 },
906     { CPU_ID_IXP1200,   CPU_CT_CTYPE_WB1, 0, 16384, 32, 32, 16384, 32, 32 }, /* XXX */
907     { 0, 0, 0, 0, 0, 0, 0, 0}
908 };
909 
910 static void get_cachetype_table(void);
911 
912 static void
913 get_cachetype_table()
914 {
915         int i;
916         u_int32_t cpuid = cpufunc_id();
917 
918         for (i = 0; cachetab[i].ct_cpuid != 0; i++) {
919                 if (cachetab[i].ct_cpuid == (cpuid & CPU_ID_CPU_MASK)) {
920                         arm_pcache_type = cachetab[i].ct_pcache_type;
921                         arm_pcache_unified = cachetab[i].ct_pcache_unified;
922                         arm_pdcache_size = cachetab[i].ct_pdcache_size;
923                         arm_pdcache_line_size =
924                             cachetab[i].ct_pdcache_line_size;
925                         arm_pdcache_ways = cachetab[i].ct_pdcache_ways;
926                         arm_picache_size = cachetab[i].ct_picache_size;
927                         arm_picache_line_size =
928                             cachetab[i].ct_picache_line_size;
929                         arm_picache_ways = cachetab[i].ct_picache_ways;
930                 }
931         }
932         arm_dcache_align = arm_pdcache_line_size;
933 
934         arm_dcache_align_mask = arm_dcache_align - 1;
935 }
936 
937 #endif /* SA110 || SA1100 || SA1111 || IXP12X0 */
938 
939 /*
940  * Cannot panic here as we may not have a console yet ...
941  */
942 
943 int
944 set_cpufuncs()
945 {
946         cputype = cpufunc_id();
947         cputype &= CPU_ID_CPU_MASK;
948 
949         /*
950          * NOTE: cpu_do_powersave defaults to off.  If we encounter a
951          * CPU type where we want to use it by default, then we set it.
952          */
953 
954 #ifdef CPU_ARM7TDMI
955         if ((cputype & CPU_ID_IMPLEMENTOR_MASK) == CPU_ID_ARM_LTD &&
956             CPU_ID_IS7(cputype) &&
957             (cputype & CPU_ID_7ARCH_MASK) == CPU_ID_7ARCH_V4T) {
958                 cpufuncs = arm7tdmi_cpufuncs;
959                 cpu_reset_needs_v4_MMU_disable = 0;
960                 get_cachetype_cp15();
961                 pmap_pte_init_generic();
962                 goto out;
963         }
964 #endif  
965 #ifdef CPU_ARM8
966         if ((cputype & CPU_ID_IMPLEMENTOR_MASK) == CPU_ID_ARM_LTD &&
967             (cputype & 0x0000f000) == 0x00008000) {
968                 cpufuncs = arm8_cpufuncs;
969                 cpu_reset_needs_v4_MMU_disable = 0;     /* XXX correct? */
970                 get_cachetype_cp15();
971                 pmap_pte_init_arm8();
972                 goto out;
973         }
974 #endif  /* CPU_ARM8 */
975 #ifdef CPU_ARM9
976         if (((cputype & CPU_ID_IMPLEMENTOR_MASK) == CPU_ID_ARM_LTD ||
977              (cputype & CPU_ID_