diff --git a/sys/arch/powerpc/ibm4xx/genassym.cf b/sys/arch/powerpc/ibm4xx/genassym.cf index b096ab3c6d67..838585f049a6 100644 --- a/sys/arch/powerpc/ibm4xx/genassym.cf +++ b/sys/arch/powerpc/ibm4xx/genassym.cf @@ -1,4 +1,4 @@ -# $NetBSD: genassym.cf,v 1.9 2003/11/26 03:51:39 simonb Exp $ +# $NetBSD: genassym.cf,v 1.10 2005/01/19 22:22:56 matt Exp $ # # Copyright (C) 1995, 1996 Wolfgang Solfrank. @@ -171,6 +171,7 @@ define CI_TEMPSAVE offsetof(struct cpu_info, ci_tempsave) define CI_DDBSAVE offsetof(struct cpu_info, ci_ddbsave) define CI_IPKDBSAVE offsetof(struct cpu_info, ci_ipkdbsave) define CI_DISISAVE offsetof(struct cpu_info, ci_disisave) +define CI_IDLESPIN offsetof(struct cpu_info, ci_idlespin) define CPUSAVE_R28 CPUSAVE_R28*sizeof(register_t) define CPUSAVE_R29 CPUSAVE_R29*sizeof(register_t) diff --git a/sys/arch/powerpc/include/asm.h b/sys/arch/powerpc/include/asm.h index 90719de77737..a82bb1034f49 100644 --- a/sys/arch/powerpc/include/asm.h +++ b/sys/arch/powerpc/include/asm.h @@ -1,4 +1,4 @@ -/* $NetBSD: asm.h,v 1.15 2003/08/08 07:14:26 matt Exp $ */ +/* $NetBSD: asm.h,v 1.16 2005/01/19 22:22:56 matt Exp $ */ /* * Copyright (C) 1995, 1996 Wolfgang Solfrank. @@ -117,6 +117,9 @@ stptr er,CI_INTSTK(tmp1); \ stptr er,CI_IDLE_PCB(tmp1); \ addi er,er,USPACE; /* space for idle_u */ \ + lis tmp2,_C_LABEL(emptyidlespin)@ha; \ + addi tmp2,tmp2,_C_LABEL(emptyidlespin)@l; \ + stptr tmp2,CI_IDLESPIN(tmp1); \ li tmp2,-1; \ stint tmp2,CI_INTRDEPTH(tmp1); \ li tmp2,0; \ diff --git a/sys/arch/powerpc/include/cpu.h b/sys/arch/powerpc/include/cpu.h index cf3818b2f926..8fd8b91d2d70 100644 --- a/sys/arch/powerpc/include/cpu.h +++ b/sys/arch/powerpc/include/cpu.h @@ -1,4 +1,4 @@ -/* $NetBSD: cpu.h,v 1.42 2004/09/22 11:32:03 yamt Exp $ */ +/* $NetBSD: cpu.h,v 1.43 2005/01/19 22:22:56 matt Exp $ */ /* * Copyright (C) 1999 Wolfgang Solfrank. @@ -93,6 +93,7 @@ struct cpu_info { register_t ci_disisave[DISISAVE_LEN]; struct cache_info ci_ci; void *ci_sysmon_cookie; + void (*ci_idlespin)(void); struct evcnt ci_ev_clock; /* clock intrs */ struct evcnt ci_ev_softclock; /* softclock intrs */ struct evcnt ci_ev_softnet; /* softnet intrs */ diff --git a/sys/arch/powerpc/oea/cpu_subr.c b/sys/arch/powerpc/oea/cpu_subr.c index 1c5d8a92c074..3004b582556b 100644 --- a/sys/arch/powerpc/oea/cpu_subr.c +++ b/sys/arch/powerpc/oea/cpu_subr.c @@ -1,4 +1,4 @@ -/* $NetBSD: cpu_subr.c,v 1.19 2005/01/11 02:09:54 chs Exp $ */ +/* $NetBSD: cpu_subr.c,v 1.20 2005/01/19 22:22:56 matt Exp $ */ /*- * Copyright (c) 2001 Matt Thomas. @@ -34,7 +34,7 @@ */ #include -__KERNEL_RCSID(0, "$NetBSD: cpu_subr.c,v 1.19 2005/01/11 02:09:54 chs Exp $"); +__KERNEL_RCSID(0, "$NetBSD: cpu_subr.c,v 1.20 2005/01/19 22:22:56 matt Exp $"); #include "opt_ppcparam.h" #include "opt_multiprocessor.h" @@ -59,6 +59,7 @@ static void cpu_enable_l3cr(register_t); static void cpu_config_l2cr(int); static void cpu_config_l3cr(int); static void cpu_print_speed(void); +static void cpu_idlespin(void); #if NSYSMON_ENVSYS > 0 static void cpu_tau_setup(struct cpu_info *); static int cpu_tau_gtredata __P((struct sysmon_envsys *, @@ -214,6 +215,24 @@ cpu_fmttab_print(const struct fmttab *fmt, register_t data) } } +void +cpu_idlespin(void) +{ + register_t msr; + + if (powersave <= 0) + return; + + __asm __volatile( + "sync;" + "mfmsr %0;" + "oris %0,%0,%1@h;" /* enter power saving mode */ + "mtmsr %0;" + "isync;" + : "=r"(msr) + : "J"(PSL_POW)); +} + void cpu_probe_cache(void) { @@ -295,6 +314,7 @@ cpu_attach_common(struct device *self, int id) ci->ci_cpuid = id; ci->ci_intrdepth = -1; ci->ci_dev = self; + ci->ci_idlespin = cpu_idlespin; pvr = mfpvr(); vers = (pvr >> 16) & 0xffff; diff --git a/sys/arch/powerpc/oea/genassym.cf b/sys/arch/powerpc/oea/genassym.cf index d9ea55f6015f..099a3bfa8cc9 100644 --- a/sys/arch/powerpc/oea/genassym.cf +++ b/sys/arch/powerpc/oea/genassym.cf @@ -1,4 +1,4 @@ -# $NetBSD: genassym.cf,v 1.7 2003/11/21 18:07:29 matt Exp $ +# $NetBSD: genassym.cf,v 1.8 2005/01/19 22:22:56 matt Exp $ # # Copyright (C) 1995, 1996 Wolfgang Solfrank. @@ -181,6 +181,7 @@ define CI_TEMPSAVE offsetof(struct cpu_info, ci_tempsave) define CI_DDBSAVE offsetof(struct cpu_info, ci_ddbsave) define CI_IPKDBSAVE offsetof(struct cpu_info, ci_ipkdbsave) define CI_DISISAVE offsetof(struct cpu_info, ci_disisave) +define CI_IDLESPIN offsetof(struct cpu_info, ci_idlespin) define CPUSAVE_R28 CPUSAVE_R28*sizeof(register_t) define CPUSAVE_R29 CPUSAVE_R29*sizeof(register_t) diff --git a/sys/arch/powerpc/powerpc/locore_subr.S b/sys/arch/powerpc/powerpc/locore_subr.S index c08cf837a090..4167c99732a4 100644 --- a/sys/arch/powerpc/powerpc/locore_subr.S +++ b/sys/arch/powerpc/powerpc/locore_subr.S @@ -1,4 +1,4 @@ -/* $NetBSD: locore_subr.S,v 1.26 2004/12/04 05:56:28 matt Exp $ */ +/* $NetBSD: locore_subr.S,v 1.27 2005/01/19 22:22:56 matt Exp $ */ /* * Copyright (c) 2001 Wasabi Systems, Inc. @@ -185,20 +185,10 @@ ASENTRY(Idle) * At this point, other routines can be called (such as uvm_pageidlezero). */ -#if defined(PPC_OEA) -/* Check if we can use power saving mode */ - lis %r8,_C_LABEL(powersave)@ha - ldint %r9,_C_LABEL(powersave)@l(%r8) - add. %r9,%r9,%r9 - ble 1f - - sync - mfmsr %r4 - oris %r4,%r4,PSL_POW@h /* enter power saving mode */ - mtmsr %r4 - isync -1: -#endif /* PPC_OEA */ + GET_CPUINFO(%r8) + ldptr %r9,CI_IDLESPIN(%r8) + mtctr %r9 + bctrl #if defined(PPC_IBM4XX) wrteei 0 /* disable interrupts while @@ -474,7 +464,8 @@ switch_return: #endif ldreg %r0,CFRAME_LR(%r1) mtlr %r0 - blr +ENTRY_NOPROFILE(emptyidlespin) + blr /* CPUINIT needs a raw blr */ /* * void