Subject: powerpc: cpu_idle implementation for systemsim The original cpu_idle hack from the systemsim git tree is a bit strange, because it unconditionally changes the native_idle function. This one instead introduces a new idle implementation that is only used on systemsim. Signed-off-by: Arnd Bergmann Index: linus-2.6/arch/powerpc/Kconfig =================================================================== --- linus-2.6.orig/arch/powerpc/Kconfig +++ linus-2.6/arch/powerpc/Kconfig @@ -375,6 +375,15 @@ config PPC_SYSTEMSIM The Full system simulator is available for download from http://www.alphaworks.ibm.com/tech/. +config SYSTEMSIM_IDLE + bool " Optimized idle loop for systemsim" + depends on PPC_SYSTEMSIM + help + Selecting this option will enable an more optimized idle loop + for running on the IBM Full System Simulator that + significantly reduces the load on the host system when + simulating an idle system. + config XICS depends on PPC_PSERIES bool Index: linus-2.6/arch/powerpc/kernel/setup_64.c =================================================================== --- linus-2.6.orig/arch/powerpc/kernel/setup_64.c +++ linus-2.6/arch/powerpc/kernel/setup_64.c @@ -557,6 +557,23 @@ static void __init emergency_stack_init( } /* + * Detect if we are running on top of the IBM Full System Simulator. + * If we are, use the optimized idle loop for that case. + */ +static void __init setup_systemsim_idle(void) +{ +#ifdef CONFIG_SYSTEMSIM_IDLE + struct device_node *mambo_node; + + mambo_node = of_find_node_by_path("/mambo"); + if (mambo_node) { + ppc_md.idle_loop = systemsim_idle; + of_node_put(mambo_node); + } +#endif +} + +/* * Called into from start_kernel, after lock_kernel has been called. * Initializes bootmem, which is unsed to manage page allocation until * mem_init is called. @@ -603,6 +620,8 @@ void __init setup_arch(char **cmdline_p) ppc_md.setup_arch(); + setup_systemsim_idle(); + /* Use the default idle loop if the platform hasn't provided one. */ if (NULL == ppc_md.idle_loop) { ppc_md.idle_loop = default_idle; Index: linus-2.6/include/asm-powerpc/machdep.h =================================================================== --- linus-2.6.orig/include/asm-powerpc/machdep.h +++ linus-2.6/include/asm-powerpc/machdep.h @@ -244,6 +244,7 @@ struct machdep_calls { extern void default_idle(void); extern void native_idle(void); +extern void systemsim_idle(void); extern struct machdep_calls ppc_md; extern char cmd_line[COMMAND_LINE_SIZE]; Index: linus-2.6/arch/powerpc/kernel/idle_systemsim.c =================================================================== --- /dev/null +++ linus-2.6/arch/powerpc/kernel/idle_systemsim.c @@ -0,0 +1,35 @@ +/* + * Idle daemon for the IBM Full System Simulator. + * + * Originally Written by Cort Dougan (cort@cs.nmt.edu) + * Copyright (c) 2003-2006 IBM Corporation + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version + * 2 of the License, or (at your option) any later version. + */ + +#include +#include + +#include + +#define SIM_HALT_CODE 126 + +static inline void systemsim_halt(void) +{ + callthru0(SIM_HALT_CODE); +} + +void systemsim_idle(void) +{ + while (1) { + while (!need_resched()) + systemsim_halt(); + + preempt_enable_no_resched(); + schedule(); + preempt_disable(); + } +} Index: linus-2.6/arch/powerpc/kernel/Makefile =================================================================== --- linus-2.6.orig/arch/powerpc/kernel/Makefile +++ linus-2.6/arch/powerpc/kernel/Makefile @@ -21,6 +21,7 @@ obj-$(CONFIG_PPC64) += setup_64.o binfm obj-$(CONFIG_PPC64) += vdso64/ obj-$(CONFIG_ALTIVEC) += vecemu.o vector.o obj-$(CONFIG_POWER4) += idle_power4.o +obj-$(CONFIG_SYSTEMSIM_IDLE) += idle_systemsim.o obj-$(CONFIG_PPC_OF) += of_device.o prom_parse.o procfs-$(CONFIG_PPC64) := proc_ppc64.o obj-$(CONFIG_PROC_FS) += $(procfs-y)