diff options
author | nwhitehorn <nwhitehorn@FreeBSD.org> | 2010-11-12 03:43:22 +0000 |
---|---|---|
committer | nwhitehorn <nwhitehorn@FreeBSD.org> | 2010-11-12 03:43:22 +0000 |
commit | b60b3b77532b00e2d6d085b6d2cf1c55a94d6690 (patch) | |
tree | d7c7eab3713ec62c4130904b95aba146f88cc89f /sys/powerpc | |
parent | 95c949e611a9c4de7cef2b654936b673a6c23ca9 (diff) | |
download | FreeBSD-src-b60b3b77532b00e2d6d085b6d2cf1c55a94d6690.zip FreeBSD-src-b60b3b77532b00e2d6d085b6d2cf1c55a94d6690.tar.gz |
Centralize CPU idle routines into powerpc/cpu.c and use the same
cpu_idle_hook mechanism that x86 uses for overriding the idle routine.
This is required for supporting ilding the CPU under PowerPC hypervisors.
Diffstat (limited to 'sys/powerpc')
-rw-r--r-- | sys/powerpc/aim/machdep.c | 58 | ||||
-rw-r--r-- | sys/powerpc/booke/machdep.c | 44 | ||||
-rw-r--r-- | sys/powerpc/powerpc/cpu.c | 100 |
3 files changed, 98 insertions, 104 deletions
diff --git a/sys/powerpc/aim/machdep.c b/sys/powerpc/aim/machdep.c index f52f7a4..456fa44 100644 --- a/sys/powerpc/aim/machdep.c +++ b/sys/powerpc/aim/machdep.c @@ -639,64 +639,6 @@ cpu_halt(void) OF_exit(); } -void -cpu_idle(int busy) -{ - register_t msr; - uint16_t vers; - - msr = mfmsr(); - vers = mfpvr() >> 16; - -#ifdef INVARIANTS - if ((msr & PSL_EE) != PSL_EE) { - struct thread *td = curthread; - printf("td msr %#lx\n", (u_long)td->td_md.md_saved_msr); - panic("ints disabled in idleproc!"); - } -#endif - CTR2(KTR_SPARE2, "cpu_idle(%d) at %d", - busy, curcpu); - if (powerpc_pow_enabled) { - if (!busy) { - critical_enter(); - cpu_idleclock(); - } - switch (vers) { - case IBM970: - case IBM970FX: - case IBM970MP: - case MPC7447A: - case MPC7448: - case MPC7450: - case MPC7455: - case MPC7457: - __asm __volatile("\ - dssall; sync; mtmsr %0; isync" - :: "r"(msr | PSL_POW)); - break; - default: - powerpc_sync(); - mtmsr(msr | PSL_POW); - isync(); - break; - } - if (!busy) { - cpu_activeclock(); - critical_exit(); - } - } - CTR2(KTR_SPARE2, "cpu_idle(%d) at %d done", - busy, curcpu); -} - -int -cpu_idle_wakeup(int cpu) -{ - - return (0); -} - int ptrace_set_pc(struct thread *td, unsigned long addr) { diff --git a/sys/powerpc/booke/machdep.c b/sys/powerpc/booke/machdep.c index b8a77a5..860c271 100644 --- a/sys/powerpc/booke/machdep.c +++ b/sys/powerpc/booke/machdep.c @@ -468,50 +468,6 @@ cpu_flush_dcache(void *ptr, size_t len) /* TBD */ } -/* - * cpu_idle - * - * Set Wait state enable. - */ -void -cpu_idle (int busy) -{ - register_t msr; - - msr = mfmsr(); - -#ifdef INVARIANTS - if ((msr & PSL_EE) != PSL_EE) { - struct thread *td = curthread; - printf("td msr %x\n", td->td_md.md_saved_msr); - panic("ints disabled in idleproc!"); - } -#endif - - CTR2(KTR_SPARE2, "cpu_idle(%d) at %d", - busy, curcpu); - if (!busy) { - critical_enter(); - cpu_idleclock(); - } - /* Freescale E500 core RM section 6.4.1. */ - msr = msr | PSL_WE; - __asm __volatile("msync; mtmsr %0; isync" :: "r" (msr)); - if (!busy) { - cpu_activeclock(); - critical_exit(); - } - CTR2(KTR_SPARE2, "cpu_idle(%d) at %d done", - busy, curcpu); -} - -int -cpu_idle_wakeup(int cpu) -{ - - return (0); -} - void spinlock_enter(void) { diff --git a/sys/powerpc/powerpc/cpu.c b/sys/powerpc/powerpc/cpu.c index 4bbfcac..e5d43d8 100644 --- a/sys/powerpc/powerpc/cpu.c +++ b/sys/powerpc/powerpc/cpu.c @@ -64,6 +64,7 @@ #include <sys/conf.h> #include <sys/cpu.h> #include <sys/kernel.h> +#include <sys/proc.h> #include <sys/sysctl.h> #include <machine/bus.h> @@ -73,12 +74,15 @@ #include <machine/smp.h> #include <machine/spr.h> -int powerpc_pow_enabled; - static void cpu_6xx_setup(int cpuid, uint16_t vers); static void cpu_e500_setup(int cpuid, uint16_t vers); static void cpu_970_setup(int cpuid, uint16_t vers); +int powerpc_pow_enabled; +void (*cpu_idle_hook)(void) = NULL; +static void cpu_idle_60x(void); +static void cpu_idle_e500(void); + struct cputab { const char *name; uint16_t version; @@ -374,6 +378,9 @@ cpu_6xx_setup(int cpuid, uint16_t vers) } printf("cpu%d: HID0 %b\n", cpuid, (int)hid0, bitmask); + + if (cpu_idle_hook == NULL) + cpu_idle_hook = cpu_idle_60x; } @@ -441,6 +448,9 @@ cpu_e500_setup(int cpuid, uint16_t vers) mtspr(SPR_HID0, hid0); printf("cpu%d: HID0 %b\n", cpuid, (int)hid0, HID0_E500_BITMASK); + + if (cpu_idle_hook == NULL) + cpu_idle_hook = cpu_idle_e500; } static void @@ -478,6 +488,8 @@ cpu_970_setup(int cpuid, uint16_t vers) : "=r" (hid0_hi) : "K" (SPR_HID0)); printf("cpu%d: HID0 %b\n", cpuid, (int)(hid0_hi), HID0_970_BITMASK); #endif + + cpu_idle_hook = cpu_idle_60x; } static int @@ -490,3 +502,87 @@ cpu_feature_bit(SYSCTL_HANDLER_ARGS) return (sysctl_handle_int(oidp, &result, 0, req)); } +void +cpu_idle(int busy) +{ + +#ifdef INVARIANTS + if ((mfmsr() & PSL_EE) != PSL_EE) { + struct thread *td = curthread; + printf("td msr %#lx\n", (u_long)td->td_md.md_saved_msr); + panic("ints disabled in idleproc!"); + } +#endif + + CTR2(KTR_SPARE2, "cpu_idle(%d) at %d", + busy, curcpu); + if (cpu_idle_hook != NULL) { + if (!busy) { + critical_enter(); + cpu_idleclock(); + } + cpu_idle_hook(); + if (!busy) { + cpu_activeclock(); + critical_exit(); + } + } + CTR2(KTR_SPARE2, "cpu_idle(%d) at %d done", + busy, curcpu); +} + +int +cpu_idle_wakeup(int cpu) +{ + return (0); +} + +static void +cpu_idle_60x(void) +{ + register_t msr; + uint16_t vers; + + if (!powerpc_pow_enabled) + return; + + msr = mfmsr(); + vers = mfpvr() >> 16; + +#ifdef AIM + switch (vers) { + case IBM970: + case IBM970FX: + case IBM970MP: + case MPC7447A: + case MPC7448: + case MPC7450: + case MPC7455: + case MPC7457: + __asm __volatile("\ + dssall; sync; mtmsr %0; isync" + :: "r"(msr | PSL_POW)); + break; + default: + powerpc_sync(); + mtmsr(msr | PSL_POW); + isync(); + break; + } +#endif +} + +static void +cpu_idle_e500(void) +{ + register_t msr; + + msr = mfmsr(); + +#ifdef E500 + /* Freescale E500 core RM section 6.4.1. */ + __asm __volatile("msync; mtmsr %0; isync" :: + "r" (msr | PSL_WE)); +#endif +} + |