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.
This commit is contained in:
Nathan Whitehorn 2010-11-12 03:43:22 +00:00
parent d25e560a15
commit 5b7ed13bc8
3 changed files with 98 additions and 104 deletions

View File

@ -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)
{

View File

@ -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)
{

View File

@ -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
}