1/*-
2 * Copyright (c) 2001 Matt Thomas.
3 * Copyright (c) 2001 Tsubai Masanari.
4 * Copyright (c) 1998, 1999, 2001 Internet Research Institute, Inc.
5 * All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 * 1. Redistributions of source code must retain the above copyright
11 *    notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 *    notice, this list of conditions and the following disclaimer in the
14 *    documentation and/or other materials provided with the distribution.
15 * 3. All advertising materials mentioning features or use of this software
16 *    must display the following acknowledgement:
17 *	This product includes software developed by
18 *	Internet Research Institute, Inc.
19 * 4. The name of the author may not be used to endorse or promote products
20 *    derived from this software without specific prior written permission.
21 *
22 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
23 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
24 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
25 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
26 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
27 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
28 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
29 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
30 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
31 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
32 */
33/*-
34 * Copyright (C) 2003 Benno Rice.
35 * All rights reserved.
36 *
37 * Redistribution and use in source and binary forms, with or without
38 * modification, are permitted provided that the following conditions
39 * are met:
40 * 1. Redistributions of source code must retain the above copyright
41 *    notice, this list of conditions and the following disclaimer.
42 * 2. Redistributions in binary form must reproduce the above copyright
43 *    notice, this list of conditions and the following disclaimer in the
44 *    documentation and/or other materials provided with the distribution.
45 *
46 * THIS SOFTWARE IS PROVIDED BY Benno Rice ``AS IS'' AND ANY EXPRESS OR
47 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
48 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
49 * IN NO EVENT SHALL TOOLS GMBH BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
50 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
51 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
52 * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
53 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
54 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
55 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
56 *
57 * from $NetBSD: cpu_subr.c,v 1.1 2003/02/03 17:10:09 matt Exp $
58 * $FreeBSD$
59 */
60
61#include <sys/param.h>
62#include <sys/systm.h>
63#include <sys/bus.h>
64#include <sys/conf.h>
65#include <sys/cpu.h>
66#include <sys/kernel.h>
67#include <sys/proc.h>
68#include <sys/sysctl.h>
69
70#include <machine/bus.h>
71#include <machine/cpu.h>
72#include <machine/hid.h>
73#include <machine/md_var.h>
74#include <machine/smp.h>
75#include <machine/spr.h>
76
77static void	cpu_6xx_setup(int cpuid, uint16_t vers);
78static void	cpu_e500_setup(int cpuid, uint16_t vers);
79static void	cpu_970_setup(int cpuid, uint16_t vers);
80
81int powerpc_pow_enabled;
82void (*cpu_idle_hook)(void) = NULL;
83static void	cpu_idle_60x(void);
84static void	cpu_idle_e500(void);
85
86struct cputab {
87	const char	*name;
88	uint16_t	version;
89	uint16_t	revfmt;
90	int		features;	/* Do not include PPC_FEATURE_32 or
91					 * PPC_FEATURE_HAS_MMU */
92	void		(*cpu_setup)(int cpuid, uint16_t vers);
93};
94#define	REVFMT_MAJMIN	1	/* %u.%u */
95#define	REVFMT_HEX	2	/* 0x%04x */
96#define	REVFMT_DEC	3	/* %u */
97static const struct cputab models[] = {
98        { "Motorola PowerPC 601",	MPC601,		REVFMT_DEC,
99	   PPC_FEATURE_HAS_FPU | PPC_FEATURE_UNIFIED_CACHE, cpu_6xx_setup },
100        { "Motorola PowerPC 602",	MPC602,		REVFMT_DEC,
101	   PPC_FEATURE_HAS_FPU, cpu_6xx_setup },
102        { "Motorola PowerPC 603",	MPC603,		REVFMT_MAJMIN,
103	   PPC_FEATURE_HAS_FPU, cpu_6xx_setup },
104        { "Motorola PowerPC 603e",	MPC603e,	REVFMT_MAJMIN,
105	   PPC_FEATURE_HAS_FPU, cpu_6xx_setup },
106        { "Motorola PowerPC 603ev",	MPC603ev,	REVFMT_MAJMIN,
107	   PPC_FEATURE_HAS_FPU, cpu_6xx_setup },
108        { "Motorola PowerPC 604",	MPC604,		REVFMT_MAJMIN,
109	   PPC_FEATURE_HAS_FPU, cpu_6xx_setup },
110        { "Motorola PowerPC 604ev",	MPC604ev,	REVFMT_MAJMIN,
111	   PPC_FEATURE_HAS_FPU, cpu_6xx_setup },
112        { "Motorola PowerPC 620",	MPC620,		REVFMT_HEX,
113	   PPC_FEATURE_64 | PPC_FEATURE_HAS_FPU, NULL },
114        { "Motorola PowerPC 750",	MPC750,		REVFMT_MAJMIN,
115	   PPC_FEATURE_HAS_FPU, cpu_6xx_setup },
116        { "IBM PowerPC 750FX",		IBM750FX,	REVFMT_MAJMIN,
117	   PPC_FEATURE_HAS_FPU, cpu_6xx_setup },
118        { "IBM PowerPC 970",		IBM970,		REVFMT_MAJMIN,
119	   PPC_FEATURE_64 | PPC_FEATURE_HAS_ALTIVEC | PPC_FEATURE_HAS_FPU,
120	   cpu_970_setup },
121        { "IBM PowerPC 970FX",		IBM970FX,	REVFMT_MAJMIN,
122	   PPC_FEATURE_64 | PPC_FEATURE_HAS_ALTIVEC | PPC_FEATURE_HAS_FPU,
123	   cpu_970_setup },
124        { "IBM PowerPC 970GX",		IBM970GX,	REVFMT_MAJMIN,
125	   PPC_FEATURE_64 | PPC_FEATURE_HAS_ALTIVEC | PPC_FEATURE_HAS_FPU,
126	   cpu_970_setup },
127        { "IBM PowerPC 970MP",		IBM970MP,	REVFMT_MAJMIN,
128	   PPC_FEATURE_64 | PPC_FEATURE_HAS_ALTIVEC | PPC_FEATURE_HAS_FPU,
129	   cpu_970_setup },
130        { "Motorola PowerPC 7400",	MPC7400,	REVFMT_MAJMIN,
131	   PPC_FEATURE_HAS_ALTIVEC | PPC_FEATURE_HAS_FPU, cpu_6xx_setup },
132        { "Motorola PowerPC 7410",	MPC7410,	REVFMT_MAJMIN,
133	   PPC_FEATURE_HAS_ALTIVEC | PPC_FEATURE_HAS_FPU, cpu_6xx_setup },
134        { "Motorola PowerPC 7450",	MPC7450,	REVFMT_MAJMIN,
135	   PPC_FEATURE_HAS_ALTIVEC | PPC_FEATURE_HAS_FPU, cpu_6xx_setup },
136        { "Motorola PowerPC 7455",	MPC7455,	REVFMT_MAJMIN,
137	   PPC_FEATURE_HAS_ALTIVEC | PPC_FEATURE_HAS_FPU, cpu_6xx_setup },
138        { "Motorola PowerPC 7457",	MPC7457,	REVFMT_MAJMIN,
139	   PPC_FEATURE_HAS_ALTIVEC | PPC_FEATURE_HAS_FPU, cpu_6xx_setup },
140        { "Motorola PowerPC 7447A",	MPC7447A,	REVFMT_MAJMIN,
141	   PPC_FEATURE_HAS_ALTIVEC | PPC_FEATURE_HAS_FPU, cpu_6xx_setup },
142        { "Motorola PowerPC 7448",	MPC7448,	REVFMT_MAJMIN,
143	   PPC_FEATURE_HAS_ALTIVEC | PPC_FEATURE_HAS_FPU, cpu_6xx_setup },
144        { "Motorola PowerPC 8240",	MPC8240,	REVFMT_MAJMIN,
145	   PPC_FEATURE_HAS_FPU, cpu_6xx_setup },
146        { "Motorola PowerPC 8245",	MPC8245,	REVFMT_MAJMIN,
147	   PPC_FEATURE_HAS_FPU, cpu_6xx_setup },
148        { "Freescale e500v1 core",	FSL_E500v1,	REVFMT_MAJMIN,
149	   0, cpu_e500_setup },
150        { "Freescale e500v2 core",	FSL_E500v2,	REVFMT_MAJMIN,
151	   0, cpu_e500_setup },
152        { "IBM Cell Broadband Engine",	IBMCELLBE,	REVFMT_MAJMIN,
153	   PPC_FEATURE_64 | PPC_FEATURE_HAS_ALTIVEC | PPC_FEATURE_HAS_FPU,
154	   NULL},
155        { "Unknown PowerPC CPU",	0,		REVFMT_HEX, 0, NULL },
156};
157
158static void	cpu_6xx_print_cacheinfo(u_int, uint16_t);
159static int	cpu_feature_bit(SYSCTL_HANDLER_ARGS);
160
161static char model[64];
162SYSCTL_STRING(_hw, HW_MODEL, model, CTLFLAG_RD, model, 0, "");
163
164int cpu_features = PPC_FEATURE_32 | PPC_FEATURE_HAS_MMU;
165SYSCTL_OPAQUE(_hw, OID_AUTO, cpu_features, CTLTYPE_INT | CTLFLAG_RD,
166    &cpu_features, sizeof(cpu_features), "IX", "PowerPC CPU features");
167
168/* Provide some user-friendly aliases for bits in cpu_features */
169SYSCTL_PROC(_hw, OID_AUTO, floatingpoint, CTLTYPE_INT | CTLFLAG_RD,
170    0, PPC_FEATURE_HAS_FPU, cpu_feature_bit, "I",
171    "Floating point instructions executed in hardware");
172SYSCTL_PROC(_hw, OID_AUTO, altivec, CTLTYPE_INT | CTLFLAG_RD,
173    0, PPC_FEATURE_HAS_ALTIVEC, cpu_feature_bit, "I", "CPU supports Altivec");
174
175void
176cpu_setup(u_int cpuid)
177{
178	u_int		pvr, maj, min;
179	uint16_t	vers, rev, revfmt;
180	uint64_t	cps;
181	const struct	cputab *cp;
182	const char	*name;
183
184	pvr = mfpvr();
185	vers = pvr >> 16;
186	rev = pvr;
187	switch (vers) {
188		case MPC7410:
189			min = (pvr >> 0) & 0xff;
190			maj = min <= 4 ? 1 : 2;
191			break;
192		case FSL_E500v1:
193		case FSL_E500v2:
194			maj = (pvr >>  4) & 0xf;
195			min = (pvr >>  0) & 0xf;
196			break;
197		default:
198			maj = (pvr >>  8) & 0xf;
199			min = (pvr >>  0) & 0xf;
200	}
201
202	for (cp = models; cp->version != 0; cp++) {
203		if (cp->version == vers)
204			break;
205	}
206
207	revfmt = cp->revfmt;
208	name = cp->name;
209	if (rev == MPC750 && pvr == 15) {
210		name = "Motorola MPC755";
211		revfmt = REVFMT_HEX;
212	}
213	strncpy(model, name, sizeof(model) - 1);
214
215	printf("cpu%d: %s revision ", cpuid, name);
216
217	switch (revfmt) {
218		case REVFMT_MAJMIN:
219			printf("%u.%u", maj, min);
220			break;
221		case REVFMT_HEX:
222			printf("0x%04x", rev);
223			break;
224		case REVFMT_DEC:
225			printf("%u", rev);
226			break;
227	}
228
229	if (cpu_est_clockrate(0, &cps) == 0)
230		printf(", %jd.%02jd MHz", cps / 1000000, (cps / 10000) % 100);
231	printf("\n");
232
233	cpu_features |= cp->features;
234	printf("cpu%d: Features %b\n", cpuid, cpu_features,
235	    PPC_FEATURE_BITMASK);
236
237	/*
238	 * Configure CPU
239	 */
240	if (cp->cpu_setup != NULL)
241		cp->cpu_setup(cpuid, vers);
242}
243
244/* Get current clock frequency for the given cpu id. */
245int
246cpu_est_clockrate(int cpu_id, uint64_t *cps)
247{
248	uint16_t	vers;
249	register_t	msr;
250
251	vers = mfpvr() >> 16;
252	msr = mfmsr();
253	mtmsr(msr & ~PSL_EE);
254
255	switch (vers) {
256		case MPC7450:
257		case MPC7455:
258		case MPC7457:
259		case MPC750:
260		case IBM750FX:
261		case MPC7400:
262		case MPC7410:
263		case MPC7447A:
264		case MPC7448:
265			mtspr(SPR_MMCR0, SPR_MMCR0_FC);
266			mtspr(SPR_PMC1, 0);
267			mtspr(SPR_MMCR0, SPR_MMCR0_PMC1SEL(PMCN_CYCLES));
268			DELAY(1000);
269			*cps = (mfspr(SPR_PMC1) * 1000) + 4999;
270			mtspr(SPR_MMCR0, SPR_MMCR0_FC);
271
272			mtmsr(msr);
273			return (0);
274		case IBM970:
275		case IBM970FX:
276		case IBM970MP:
277			isync();
278			mtspr(SPR_970MMCR0, SPR_MMCR0_FC);
279			isync();
280			mtspr(SPR_970MMCR1, 0);
281			mtspr(SPR_970MMCRA, 0);
282			mtspr(SPR_970PMC1, 0);
283			mtspr(SPR_970MMCR0,
284			    SPR_970MMCR0_PMC1SEL(PMC970N_CYCLES));
285			isync();
286			DELAY(1000);
287			powerpc_sync();
288			mtspr(SPR_970MMCR0, SPR_MMCR0_FC);
289			*cps = (mfspr(SPR_970PMC1) * 1000) + 4999;
290
291			mtmsr(msr);
292			return (0);
293	}
294
295	return (ENXIO);
296}
297
298void
299cpu_6xx_setup(int cpuid, uint16_t vers)
300{
301	register_t hid0, pvr;
302	const char *bitmask;
303
304	hid0 = mfspr(SPR_HID0);
305	pvr = mfpvr();
306
307	/*
308	 * Configure power-saving mode.
309	 */
310	switch (vers) {
311		case MPC603:
312		case MPC603e:
313		case MPC603ev:
314		case MPC604ev:
315		case MPC750:
316		case IBM750FX:
317		case MPC7400:
318		case MPC7410:
319		case MPC8240:
320		case MPC8245:
321			/* Select DOZE mode. */
322			hid0 &= ~(HID0_DOZE | HID0_NAP | HID0_SLEEP);
323			hid0 |= HID0_DOZE | HID0_DPM;
324			powerpc_pow_enabled = 1;
325			break;
326
327		case MPC7448:
328		case MPC7447A:
329		case MPC7457:
330		case MPC7455:
331		case MPC7450:
332			/* Enable the 7450 branch caches */
333			hid0 |= HID0_SGE | HID0_BTIC;
334			hid0 |= HID0_LRSTK | HID0_FOLD | HID0_BHT;
335			/* Disable BTIC on 7450 Rev 2.0 or earlier and on 7457 */
336			if (((pvr >> 16) == MPC7450 && (pvr & 0xFFFF) <= 0x0200)
337					|| (pvr >> 16) == MPC7457)
338				hid0 &= ~HID0_BTIC;
339			/* Select NAP mode. */
340			hid0 &= ~(HID0_DOZE | HID0_NAP | HID0_SLEEP);
341			hid0 |= HID0_NAP | HID0_DPM;
342			powerpc_pow_enabled = 1;
343			break;
344
345		default:
346			/* No power-saving mode is available. */ ;
347	}
348
349	switch (vers) {
350		case IBM750FX:
351		case MPC750:
352			hid0 &= ~HID0_DBP;		/* XXX correct? */
353			hid0 |= HID0_EMCP | HID0_BTIC | HID0_SGE | HID0_BHT;
354			break;
355
356		case MPC7400:
357		case MPC7410:
358			hid0 &= ~HID0_SPD;
359			hid0 |= HID0_EMCP | HID0_BTIC | HID0_SGE | HID0_BHT;
360			hid0 |= HID0_EIEC;
361			break;
362
363	}
364
365	mtspr(SPR_HID0, hid0);
366
367	if (bootverbose)
368		cpu_6xx_print_cacheinfo(cpuid, vers);
369
370	switch (vers) {
371		case MPC7447A:
372		case MPC7448:
373		case MPC7450:
374		case MPC7455:
375		case MPC7457:
376			bitmask = HID0_7450_BITMASK;
377			break;
378		default:
379			bitmask = HID0_BITMASK;
380			break;
381	}
382
383	printf("cpu%d: HID0 %b\n", cpuid, (int)hid0, bitmask);
384
385	if (cpu_idle_hook == NULL)
386		cpu_idle_hook = cpu_idle_60x;
387}
388
389
390static void
391cpu_6xx_print_cacheinfo(u_int cpuid, uint16_t vers)
392{
393	register_t hid;
394
395	hid = mfspr(SPR_HID0);
396	printf("cpu%u: ", cpuid);
397	printf("L1 I-cache %sabled, ", (hid & HID0_ICE) ? "en" : "dis");
398	printf("L1 D-cache %sabled\n", (hid & HID0_DCE) ? "en" : "dis");
399
400	printf("cpu%u: ", cpuid);
401  	if (mfspr(SPR_L2CR) & L2CR_L2E) {
402		switch (vers) {
403		case MPC7450:
404		case MPC7455:
405		case MPC7457:
406			printf("256KB L2 cache, ");
407			if (mfspr(SPR_L3CR) & L3CR_L3E)
408				printf("%cMB L3 backside cache",
409				    mfspr(SPR_L3CR) & L3CR_L3SIZ ? '2' : '1');
410			else
411				printf("L3 cache disabled");
412			printf("\n");
413			break;
414		case IBM750FX:
415			printf("512KB L2 cache\n");
416			break;
417		default:
418			switch (mfspr(SPR_L2CR) & L2CR_L2SIZ) {
419			case L2SIZ_256K:
420				printf("256KB ");
421				break;
422			case L2SIZ_512K:
423				printf("512KB ");
424				break;
425			case L2SIZ_1M:
426				printf("1MB ");
427				break;
428			}
429			printf("write-%s", (mfspr(SPR_L2CR) & L2CR_L2WT)
430			    ? "through" : "back");
431			if (mfspr(SPR_L2CR) & L2CR_L2PE)
432				printf(", with parity");
433			printf(" backside cache\n");
434			break;
435		}
436	} else
437		printf("L2 cache disabled\n");
438}
439
440static void
441cpu_e500_setup(int cpuid, uint16_t vers)
442{
443	register_t hid0;
444
445	hid0 = mfspr(SPR_HID0);
446
447	/* Programe power-management mode. */
448	hid0 &= ~(HID0_DOZE | HID0_NAP | HID0_SLEEP);
449	hid0 |= HID0_DOZE;
450
451	mtspr(SPR_HID0, hid0);
452
453	printf("cpu%d: HID0 %b\n", cpuid, (int)hid0, HID0_E500_BITMASK);
454
455	if (cpu_idle_hook == NULL)
456		cpu_idle_hook = cpu_idle_e500;
457}
458
459static void
460cpu_970_setup(int cpuid, uint16_t vers)
461{
462#ifdef AIM
463	uint32_t hid0_hi, hid0_lo;
464
465	__asm __volatile ("mfspr %0,%2; clrldi %1,%0,32; srdi %0,%0,32;"
466	    : "=r" (hid0_hi), "=r" (hid0_lo) : "K" (SPR_HID0));
467
468	/* Configure power-saving mode */
469	switch (vers) {
470	case IBM970MP:
471		hid0_hi |= (HID0_DEEPNAP | HID0_NAP | HID0_DPM);
472		hid0_hi &= ~HID0_DOZE;
473		break;
474	default:
475		hid0_hi |= (HID0_NAP | HID0_DPM);
476		hid0_hi &= ~(HID0_DOZE | HID0_DEEPNAP);
477		break;
478	}
479	powerpc_pow_enabled = 1;
480
481	__asm __volatile (" \
482		sync; isync;					\
483		sldi	%0,%0,32; or %0,%0,%1;			\
484		mtspr	%2, %0;					\
485		mfspr   %0, %2; mfspr   %0, %2; mfspr   %0, %2; \
486		mfspr   %0, %2; mfspr   %0, %2; mfspr   %0, %2; \
487		sync; isync"
488	    :: "r" (hid0_hi), "r"(hid0_lo), "K" (SPR_HID0));
489
490	__asm __volatile ("mfspr %0,%1; srdi %0,%0,32;"
491	    : "=r" (hid0_hi) : "K" (SPR_HID0));
492	printf("cpu%d: HID0 %b\n", cpuid, (int)(hid0_hi), HID0_970_BITMASK);
493#endif
494
495	cpu_idle_hook = cpu_idle_60x;
496}
497
498static int
499cpu_feature_bit(SYSCTL_HANDLER_ARGS)
500{
501	int result;
502
503	result = (cpu_features & arg2) ? 1 : 0;
504
505	return (sysctl_handle_int(oidp, &result, 0, req));
506}
507
508void
509cpu_idle(int busy)
510{
511
512#ifdef INVARIANTS
513	if ((mfmsr() & PSL_EE) != PSL_EE) {
514		struct thread *td = curthread;
515		printf("td msr %#lx\n", (u_long)td->td_md.md_saved_msr);
516		panic("ints disabled in idleproc!");
517	}
518#endif
519
520	CTR2(KTR_SPARE2, "cpu_idle(%d) at %d",
521	    busy, curcpu);
522	if (cpu_idle_hook != NULL) {
523		if (!busy) {
524			critical_enter();
525			cpu_idleclock();
526		}
527		cpu_idle_hook();
528		if (!busy) {
529			cpu_activeclock();
530			critical_exit();
531		}
532	}
533	CTR2(KTR_SPARE2, "cpu_idle(%d) at %d done",
534	    busy, curcpu);
535}
536
537int
538cpu_idle_wakeup(int cpu)
539{
540	return (0);
541}
542
543static void
544cpu_idle_60x(void)
545{
546	register_t msr;
547	uint16_t vers;
548
549	if (!powerpc_pow_enabled)
550		return;
551
552	msr = mfmsr();
553	vers = mfpvr() >> 16;
554
555#ifdef AIM
556	switch (vers) {
557	case IBM970:
558	case IBM970FX:
559	case IBM970MP:
560	case MPC7447A:
561	case MPC7448:
562	case MPC7450:
563	case MPC7455:
564	case MPC7457:
565		__asm __volatile("\
566			    dssall; sync; mtmsr %0; isync"
567			    :: "r"(msr | PSL_POW));
568		break;
569	default:
570		powerpc_sync();
571		mtmsr(msr | PSL_POW);
572		isync();
573		break;
574	}
575#endif
576}
577
578static void
579cpu_idle_e500(void)
580{
581	register_t msr;
582
583	msr = mfmsr();
584
585#ifdef E500
586	/* Freescale E500 core RM section 6.4.1. */
587	__asm __volatile("msync; mtmsr %0; isync" ::
588	    "r" (msr | PSL_WE));
589#endif
590}
591
592