xref: /freebsd/sys/arm/arm/cpufunc.c (revision 148a8da8)
1 /*	$NetBSD: cpufunc.c,v 1.65 2003/11/05 12:53:15 scw Exp $	*/
2 
3 /*-
4  * SPDX-License-Identifier: BSD-4-Clause
5  *
6  * arm9 support code Copyright (C) 2001 ARM Ltd
7  * Copyright (c) 1997 Mark Brinicombe.
8  * Copyright (c) 1997 Causality Limited
9  * All rights reserved.
10  *
11  * Redistribution and use in source and binary forms, with or without
12  * modification, are permitted provided that the following conditions
13  * are met:
14  * 1. Redistributions of source code must retain the above copyright
15  *    notice, this list of conditions and the following disclaimer.
16  * 2. Redistributions in binary form must reproduce the above copyright
17  *    notice, this list of conditions and the following disclaimer in the
18  *    documentation and/or other materials provided with the distribution.
19  * 3. All advertising materials mentioning features or use of this software
20  *    must display the following acknowledgement:
21  *	This product includes software developed by Causality Limited.
22  * 4. The name of Causality Limited may not be used to endorse or promote
23  *    products derived from this software without specific prior written
24  *    permission.
25  *
26  * THIS SOFTWARE IS PROVIDED BY CAUSALITY LIMITED ``AS IS'' AND ANY EXPRESS
27  * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
28  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
29  * DISCLAIMED. IN NO EVENT SHALL CAUSALITY LIMITED BE LIABLE FOR ANY DIRECT,
30  * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
31  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
32  * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
33  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
34  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
35  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
36  * SUCH DAMAGE.
37  *
38  * RiscBSD kernel project
39  *
40  * cpufuncs.c
41  *
42  * C functions for supporting CPU / MMU / TLB specific operations.
43  *
44  * Created      : 30/01/97
45  */
46 #include <sys/cdefs.h>
47 __FBSDID("$FreeBSD$");
48 
49 #include <sys/param.h>
50 #include <sys/systm.h>
51 #include <sys/lock.h>
52 #include <sys/mutex.h>
53 #include <sys/bus.h>
54 #include <machine/bus.h>
55 #include <machine/cpu.h>
56 #include <machine/disassem.h>
57 
58 #include <vm/vm.h>
59 #include <vm/pmap.h>
60 #include <vm/uma.h>
61 
62 #include <machine/cpufunc.h>
63 
64 /* PRIMARY CACHE VARIABLES */
65 int	arm_picache_size;
66 int	arm_picache_line_size;
67 int	arm_picache_ways;
68 
69 int	arm_pdcache_size;	/* and unified */
70 int	arm_pdcache_line_size;
71 int	arm_pdcache_ways;
72 
73 int	arm_pcache_type;
74 int	arm_pcache_unified;
75 
76 int	arm_dcache_align;
77 int	arm_dcache_align_mask;
78 
79 u_int	arm_cache_level;
80 u_int	arm_cache_type[14];
81 u_int	arm_cache_loc;
82 
83 #if defined(CPU_ARM9E)
84 static void arm10_setup(void);
85 #endif
86 #ifdef CPU_MV_PJ4B
87 static void pj4bv7_setup(void);
88 #endif
89 #if defined(CPU_ARM1176)
90 static void arm11x6_setup(void);
91 #endif
92 #if defined(CPU_CORTEXA) || defined(CPU_KRAIT)
93 static void cortexa_setup(void);
94 #endif
95 
96 #if defined(CPU_ARM9E)
97 struct cpu_functions armv5_ec_cpufuncs = {
98 	/* CPU functions */
99 
100 	cpufunc_nullop,			/* cpwait		*/
101 
102 	/* MMU functions */
103 
104 	cpufunc_control,		/* control		*/
105 	armv5_ec_setttb,		/* Setttb		*/
106 
107 	/* TLB functions */
108 
109 	armv4_tlb_flushID,		/* tlb_flushID		*/
110 	arm9_tlb_flushID_SE,		/* tlb_flushID_SE	*/
111 	armv4_tlb_flushD,		/* tlb_flushD		*/
112 	armv4_tlb_flushD_SE,		/* tlb_flushD_SE	*/
113 
114 	/* Cache operations */
115 
116 	armv5_ec_icache_sync_range,	/* icache_sync_range	*/
117 
118 	armv5_ec_dcache_wbinv_all,	/* dcache_wbinv_all	*/
119 	armv5_ec_dcache_wbinv_range,	/* dcache_wbinv_range	*/
120 	armv5_ec_dcache_inv_range,	/* dcache_inv_range	*/
121 	armv5_ec_dcache_wb_range,	/* dcache_wb_range	*/
122 
123 	armv4_idcache_inv_all,		/* idcache_inv_all	*/
124 	armv5_ec_idcache_wbinv_all,	/* idcache_wbinv_all	*/
125 	armv5_ec_idcache_wbinv_range,	/* idcache_wbinv_range	*/
126 
127 	cpufunc_nullop,                 /* l2cache_wbinv_all    */
128 	(void *)cpufunc_nullop,         /* l2cache_wbinv_range  */
129       	(void *)cpufunc_nullop,         /* l2cache_inv_range    */
130 	(void *)cpufunc_nullop,         /* l2cache_wb_range     */
131 	(void *)cpufunc_nullop,         /* l2cache_drain_writebuf */
132 
133 	/* Other functions */
134 
135 	armv4_drain_writebuf,		/* drain_writebuf	*/
136 
137 	(void *)cpufunc_nullop,		/* sleep		*/
138 
139 	/* Soft functions */
140 
141 	arm9_context_switch,		/* context_switch	*/
142 
143 	arm10_setup			/* cpu setup		*/
144 
145 };
146 
147 struct cpu_functions sheeva_cpufuncs = {
148 	/* CPU functions */
149 
150 	cpufunc_nullop,			/* cpwait		*/
151 
152 	/* MMU functions */
153 
154 	cpufunc_control,		/* control		*/
155 	sheeva_setttb,			/* Setttb		*/
156 
157 	/* TLB functions */
158 
159 	armv4_tlb_flushID,		/* tlb_flushID		*/
160 	arm9_tlb_flushID_SE,		/* tlb_flushID_SE	*/
161 	armv4_tlb_flushD,		/* tlb_flushD		*/
162 	armv4_tlb_flushD_SE,		/* tlb_flushD_SE	*/
163 
164 	/* Cache operations */
165 
166 	armv5_ec_icache_sync_range,	/* icache_sync_range	*/
167 
168 	armv5_ec_dcache_wbinv_all,	/* dcache_wbinv_all	*/
169 	sheeva_dcache_wbinv_range,	/* dcache_wbinv_range	*/
170 	sheeva_dcache_inv_range,	/* dcache_inv_range	*/
171 	sheeva_dcache_wb_range,		/* dcache_wb_range	*/
172 
173 	armv4_idcache_inv_all,		/* idcache_inv_all	*/
174 	armv5_ec_idcache_wbinv_all,	/* idcache_wbinv_all	*/
175 	sheeva_idcache_wbinv_range,	/* idcache_wbinv_all	*/
176 
177 	sheeva_l2cache_wbinv_all,	/* l2cache_wbinv_all    */
178 	sheeva_l2cache_wbinv_range,	/* l2cache_wbinv_range  */
179 	sheeva_l2cache_inv_range,	/* l2cache_inv_range    */
180 	sheeva_l2cache_wb_range,	/* l2cache_wb_range     */
181 	(void *)cpufunc_nullop,         /* l2cache_drain_writebuf */
182 
183 	/* Other functions */
184 
185 	armv4_drain_writebuf,		/* drain_writebuf	*/
186 
187 	sheeva_cpu_sleep,		/* sleep		*/
188 
189 	/* Soft functions */
190 
191 	arm9_context_switch,		/* context_switch	*/
192 
193 	arm10_setup			/* cpu setup		*/
194 };
195 #endif /* CPU_ARM9E */
196 
197 #ifdef CPU_MV_PJ4B
198 struct cpu_functions pj4bv7_cpufuncs = {
199 
200 	/* Cache operations */
201 	.cf_l2cache_wbinv_all = (void *)cpufunc_nullop,
202 	.cf_l2cache_wbinv_range = (void *)cpufunc_nullop,
203 	.cf_l2cache_inv_range = (void *)cpufunc_nullop,
204 	.cf_l2cache_wb_range = (void *)cpufunc_nullop,
205 	.cf_l2cache_drain_writebuf = (void *)cpufunc_nullop,
206 
207 	/* Other functions */
208 	.cf_sleep = (void *)cpufunc_nullop,
209 
210 	/* Soft functions */
211 	.cf_setup = pj4bv7_setup
212 };
213 #endif /* CPU_MV_PJ4B */
214 
215 #if defined(CPU_ARM1176)
216 struct cpu_functions arm1176_cpufuncs = {
217 
218 	/* Cache operations */
219 	.cf_l2cache_wbinv_all = (void *)cpufunc_nullop,
220 	.cf_l2cache_wbinv_range = (void *)cpufunc_nullop,
221 	.cf_l2cache_inv_range = (void *)cpufunc_nullop,
222 	.cf_l2cache_wb_range = (void *)cpufunc_nullop,
223 	.cf_l2cache_drain_writebuf = (void *)cpufunc_nullop,
224 
225 	/* Other functions */
226 	.cf_sleep = arm11x6_sleep,
227 
228 	/* Soft functions */
229 	.cf_setup = arm11x6_setup
230 };
231 #endif /*CPU_ARM1176 */
232 
233 #if defined(CPU_CORTEXA) || defined(CPU_KRAIT)
234 struct cpu_functions cortexa_cpufuncs = {
235 
236 	/* Cache operations */
237 
238 	/*
239 	 * Note: For CPUs using the PL310 the L2 ops are filled in when the
240 	 * L2 cache controller is actually enabled.
241 	 */
242 	.cf_l2cache_wbinv_all = cpufunc_nullop,
243 	.cf_l2cache_wbinv_range = (void *)cpufunc_nullop,
244 	.cf_l2cache_inv_range = (void *)cpufunc_nullop,
245 	.cf_l2cache_wb_range = (void *)cpufunc_nullop,
246 	.cf_l2cache_drain_writebuf = (void *)cpufunc_nullop,
247 
248 	/* Other functions */
249 	.cf_sleep = armv7_cpu_sleep,
250 
251 	/* Soft functions */
252 	.cf_setup = cortexa_setup
253 };
254 #endif /* CPU_CORTEXA || CPU_KRAIT */
255 
256 /*
257  * Global constants also used by locore.s
258  */
259 
260 struct cpu_functions cpufuncs;
261 u_int cputype;
262 #if __ARM_ARCH <= 5
263 u_int cpu_reset_needs_v4_MMU_disable;	/* flag used in locore-v4.s */
264 #endif
265 
266 #if defined (CPU_ARM9E) ||	\
267   defined(CPU_ARM1176) ||	\
268   defined(CPU_MV_PJ4B) ||			\
269   defined(CPU_CORTEXA) || defined(CPU_KRAIT)
270 
271 static void get_cachetype_cp15(void);
272 
273 /* Additional cache information local to this file.  Log2 of some of the
274    above numbers.  */
275 static int	arm_dcache_l2_nsets;
276 static int	arm_dcache_l2_assoc;
277 static int	arm_dcache_l2_linesize;
278 
279 static void
280 get_cachetype_cp15(void)
281 {
282 	u_int ctype, isize, dsize, cpuid;
283 	u_int clevel, csize, i, sel;
284 	u_int multiplier;
285 	u_char type;
286 
287 	ctype = cp15_ctr_get();
288 	cpuid = cp15_midr_get();
289 	/*
290 	 * ...and thus spake the ARM ARM:
291 	 *
292 	 * If an <opcode2> value corresponding to an unimplemented or
293 	 * reserved ID register is encountered, the System Control
294 	 * processor returns the value of the main ID register.
295 	 */
296 	if (ctype == cpuid)
297 		goto out;
298 
299 	if (CPU_CT_FORMAT(ctype) == CPU_CT_ARMV7) {
300 		__asm __volatile("mrc p15, 1, %0, c0, c0, 1"
301 		    : "=r" (clevel));
302 		arm_cache_level = clevel;
303 		arm_cache_loc = CPU_CLIDR_LOC(arm_cache_level);
304 		i = 0;
305 		while ((type = (clevel & 0x7)) && i < 7) {
306 			if (type == CACHE_DCACHE || type == CACHE_UNI_CACHE ||
307 			    type == CACHE_SEP_CACHE) {
308 				sel = i << 1;
309 				__asm __volatile("mcr p15, 2, %0, c0, c0, 0"
310 				    : : "r" (sel));
311 				__asm __volatile("mrc p15, 1, %0, c0, c0, 0"
312 				    : "=r" (csize));
313 				arm_cache_type[sel] = csize;
314 				arm_dcache_align = 1 <<
315 				    (CPUV7_CT_xSIZE_LEN(csize) + 4);
316 				arm_dcache_align_mask = arm_dcache_align - 1;
317 			}
318 			if (type == CACHE_ICACHE || type == CACHE_SEP_CACHE) {
319 				sel = (i << 1) | 1;
320 				__asm __volatile("mcr p15, 2, %0, c0, c0, 0"
321 				    : : "r" (sel));
322 				__asm __volatile("mrc p15, 1, %0, c0, c0, 0"
323 				    : "=r" (csize));
324 				arm_cache_type[sel] = csize;
325 			}
326 			i++;
327 			clevel >>= 3;
328 		}
329 	} else {
330 		if ((ctype & CPU_CT_S) == 0)
331 			arm_pcache_unified = 1;
332 
333 		/*
334 		 * If you want to know how this code works, go read the ARM ARM.
335 		 */
336 
337 		arm_pcache_type = CPU_CT_CTYPE(ctype);
338 
339 		if (arm_pcache_unified == 0) {
340 			isize = CPU_CT_ISIZE(ctype);
341 			multiplier = (isize & CPU_CT_xSIZE_M) ? 3 : 2;
342 			arm_picache_line_size = 1U << (CPU_CT_xSIZE_LEN(isize) + 3);
343 			if (CPU_CT_xSIZE_ASSOC(isize) == 0) {
344 				if (isize & CPU_CT_xSIZE_M)
345 					arm_picache_line_size = 0; /* not present */
346 				else
347 					arm_picache_ways = 1;
348 			} else {
349 				arm_picache_ways = multiplier <<
350 				    (CPU_CT_xSIZE_ASSOC(isize) - 1);
351 			}
352 			arm_picache_size = multiplier << (CPU_CT_xSIZE_SIZE(isize) + 8);
353 		}
354 
355 		dsize = CPU_CT_DSIZE(ctype);
356 		multiplier = (dsize & CPU_CT_xSIZE_M) ? 3 : 2;
357 		arm_pdcache_line_size = 1U << (CPU_CT_xSIZE_LEN(dsize) + 3);
358 		if (CPU_CT_xSIZE_ASSOC(dsize) == 0) {
359 			if (dsize & CPU_CT_xSIZE_M)
360 				arm_pdcache_line_size = 0; /* not present */
361 			else
362 				arm_pdcache_ways = 1;
363 		} else {
364 			arm_pdcache_ways = multiplier <<
365 			    (CPU_CT_xSIZE_ASSOC(dsize) - 1);
366 		}
367 		arm_pdcache_size = multiplier << (CPU_CT_xSIZE_SIZE(dsize) + 8);
368 
369 		arm_dcache_align = arm_pdcache_line_size;
370 
371 		arm_dcache_l2_assoc = CPU_CT_xSIZE_ASSOC(dsize) + multiplier - 2;
372 		arm_dcache_l2_linesize = CPU_CT_xSIZE_LEN(dsize) + 3;
373 		arm_dcache_l2_nsets = 6 + CPU_CT_xSIZE_SIZE(dsize) -
374 		    CPU_CT_xSIZE_ASSOC(dsize) - CPU_CT_xSIZE_LEN(dsize);
375 
376 	out:
377 		arm_dcache_align_mask = arm_dcache_align - 1;
378 	}
379 }
380 #endif /* ARM9 || XSCALE */
381 
382 /*
383  * Cannot panic here as we may not have a console yet ...
384  */
385 
386 int
387 set_cpufuncs(void)
388 {
389 	cputype = cp15_midr_get();
390 	cputype &= CPU_ID_CPU_MASK;
391 
392 #if defined(CPU_ARM9E)
393 	if (cputype == CPU_ID_MV88FR131 || cputype == CPU_ID_MV88FR571_VD ||
394 	    cputype == CPU_ID_MV88FR571_41) {
395 		uint32_t sheeva_ctrl;
396 
397 		sheeva_ctrl = (MV_DC_STREAM_ENABLE | MV_BTB_DISABLE |
398 		    MV_L2_ENABLE);
399 		/*
400 		 * Workaround for Marvell MV78100 CPU: Cache prefetch
401 		 * mechanism may affect the cache coherency validity,
402 		 * so it needs to be disabled.
403 		 *
404 		 * Refer to errata document MV-S501058-00C.pdf (p. 3.1
405 		 * L2 Prefetching Mechanism) for details.
406 		 */
407 		if (cputype == CPU_ID_MV88FR571_VD ||
408 		    cputype == CPU_ID_MV88FR571_41)
409 			sheeva_ctrl |= MV_L2_PREFETCH_DISABLE;
410 
411 		sheeva_control_ext(0xffffffff & ~MV_WA_ENABLE, sheeva_ctrl);
412 
413 		cpufuncs = sheeva_cpufuncs;
414 		get_cachetype_cp15();
415 		pmap_pte_init_generic();
416 		goto out;
417 	} else if (cputype == CPU_ID_ARM926EJS) {
418 		cpufuncs = armv5_ec_cpufuncs;
419 		get_cachetype_cp15();
420 		pmap_pte_init_generic();
421 		goto out;
422 	}
423 #endif /* CPU_ARM9E */
424 #if defined(CPU_ARM1176)
425 	if (cputype == CPU_ID_ARM1176JZS) {
426 		cpufuncs = arm1176_cpufuncs;
427 		get_cachetype_cp15();
428 		goto out;
429 	}
430 #endif /* CPU_ARM1176 */
431 #if defined(CPU_CORTEXA) || defined(CPU_KRAIT)
432 	switch(cputype & CPU_ID_SCHEME_MASK) {
433 	case CPU_ID_CORTEXA5:
434 	case CPU_ID_CORTEXA7:
435 	case CPU_ID_CORTEXA8:
436 	case CPU_ID_CORTEXA9:
437 	case CPU_ID_CORTEXA12:
438 	case CPU_ID_CORTEXA15:
439 	case CPU_ID_CORTEXA53:
440 	case CPU_ID_CORTEXA57:
441 	case CPU_ID_CORTEXA72:
442 	case CPU_ID_KRAIT300:
443 		cpufuncs = cortexa_cpufuncs;
444 		get_cachetype_cp15();
445 		goto out;
446 	default:
447 		break;
448 	}
449 #endif /* CPU_CORTEXA || CPU_KRAIT */
450 
451 #if defined(CPU_MV_PJ4B)
452 	if (cputype == CPU_ID_MV88SV581X_V7 ||
453 	    cputype == CPU_ID_MV88SV584X_V7 ||
454 	    cputype == CPU_ID_ARM_88SV581X_V7) {
455 		cpufuncs = pj4bv7_cpufuncs;
456 		get_cachetype_cp15();
457 		goto out;
458 	}
459 #endif /* CPU_MV_PJ4B */
460 
461 	/*
462 	 * Bzzzz. And the answer was ...
463 	 */
464 	panic("No support for this CPU type (%08x) in kernel", cputype);
465 	return(ARCHITECTURE_NOT_PRESENT);
466 out:
467 	uma_set_align(arm_dcache_align_mask);
468 	return (0);
469 }
470 
471 /*
472  * CPU Setup code
473  */
474 
475 #if defined(CPU_ARM9E)
476 static void
477 arm10_setup(void)
478 {
479 	int cpuctrl, cpuctrlmask;
480 
481 	cpuctrl = CPU_CONTROL_MMU_ENABLE | CPU_CONTROL_SYST_ENABLE
482 	    | CPU_CONTROL_IC_ENABLE | CPU_CONTROL_DC_ENABLE
483 	    | CPU_CONTROL_WBUF_ENABLE | CPU_CONTROL_BPRD_ENABLE;
484 	cpuctrlmask = CPU_CONTROL_MMU_ENABLE | CPU_CONTROL_SYST_ENABLE
485 	    | CPU_CONTROL_IC_ENABLE | CPU_CONTROL_DC_ENABLE
486 	    | CPU_CONTROL_WBUF_ENABLE | CPU_CONTROL_ROM_ENABLE
487 	    | CPU_CONTROL_BEND_ENABLE | CPU_CONTROL_AFLT_ENABLE
488 	    | CPU_CONTROL_BPRD_ENABLE
489 	    | CPU_CONTROL_ROUNDROBIN | CPU_CONTROL_CPCLK;
490 
491 #ifndef ARM32_DISABLE_ALIGNMENT_FAULTS
492 	cpuctrl |= CPU_CONTROL_AFLT_ENABLE;
493 #endif
494 
495 #ifdef __ARMEB__
496 	cpuctrl |= CPU_CONTROL_BEND_ENABLE;
497 #endif
498 
499 	/* Clear out the cache */
500 	cpu_idcache_wbinv_all();
501 
502 	/* Now really make sure they are clean.  */
503 	__asm __volatile ("mcr\tp15, 0, r0, c7, c7, 0" : : );
504 
505 	if (vector_page == ARM_VECTORS_HIGH)
506 		cpuctrl |= CPU_CONTROL_VECRELOC;
507 
508 	/* Set the control register */
509 	cpu_control(0xffffffff, cpuctrl);
510 
511 	/* And again. */
512 	cpu_idcache_wbinv_all();
513 }
514 #endif	/* CPU_ARM9E || CPU_ARM10 */
515 
516 #if defined(CPU_ARM1176) \
517  || defined(CPU_MV_PJ4B) \
518  || defined(CPU_CORTEXA) || defined(CPU_KRAIT)
519 static __inline void
520 cpu_scc_setup_ccnt(void)
521 {
522 /* This is how you give userland access to the CCNT and PMCn
523  * registers.
524  * BEWARE! This gives write access also, which may not be what
525  * you want!
526  */
527 #ifdef _PMC_USER_READ_WRITE_
528 	/* Set PMUSERENR[0] to allow userland access */
529 	cp15_pmuserenr_set(1);
530 #endif
531 #if defined(CPU_ARM1176)
532 	/* Set PMCR[2,0] to enable counters and reset CCNT */
533 	cp15_pmcr_set(5);
534 #else
535 	/* Set up the PMCCNTR register as a cyclecounter:
536 	 * Set PMINTENCLR to 0xFFFFFFFF to block interrupts
537 	 * Set PMCR[2,0] to enable counters and reset CCNT
538 	 * Set PMCNTENSET to 0x80000000 to enable CCNT */
539 	cp15_pminten_clr(0xFFFFFFFF);
540 	cp15_pmcr_set(5);
541 	cp15_pmcnten_set(0x80000000);
542 #endif
543 }
544 #endif
545 
546 #if defined(CPU_ARM1176)
547 static void
548 arm11x6_setup(void)
549 {
550 	uint32_t auxctrl, auxctrl_wax;
551 	uint32_t tmp, tmp2;
552 	uint32_t cpuid;
553 
554 	cpuid = cp15_midr_get();
555 
556 	auxctrl = 0;
557 	auxctrl_wax = ~0;
558 
559 	/*
560 	 * Enable an errata workaround
561 	 */
562 	if ((cpuid & CPU_ID_CPU_MASK) == CPU_ID_ARM1176JZS) { /* ARM1176JZSr0 */
563 		auxctrl = ARM1176_AUXCTL_PHD;
564 		auxctrl_wax = ~ARM1176_AUXCTL_PHD;
565 	}
566 
567 	tmp = cp15_actlr_get();
568 	tmp2 = tmp;
569 	tmp &= auxctrl_wax;
570 	tmp |= auxctrl;
571 	if (tmp != tmp2)
572 		cp15_actlr_set(tmp);
573 
574 	cpu_scc_setup_ccnt();
575 }
576 #endif  /* CPU_ARM1176 */
577 
578 #ifdef CPU_MV_PJ4B
579 static void
580 pj4bv7_setup(void)
581 {
582 
583 	pj4b_config();
584 	cpu_scc_setup_ccnt();
585 }
586 #endif /* CPU_MV_PJ4B */
587 
588 #if defined(CPU_CORTEXA) || defined(CPU_KRAIT)
589 static void
590 cortexa_setup(void)
591 {
592 
593 	cpu_scc_setup_ccnt();
594 }
595 #endif  /* CPU_CORTEXA || CPU_KRAIT */
596