aboutsummaryrefslogtreecommitdiffstats
path: root/arch/powerpc/kernel/idle_power4.S
diff options
context:
space:
mode:
authorPaul Mackerras <paulus@samba.org>2006-04-18 07:49:11 -0400
committerPaul Mackerras <paulus@samba.org>2006-04-18 07:49:11 -0400
commitf39224a8c1828bdd327539da72a53d8a13595838 (patch)
treecc9e9139e2e7e2e36774e5c52a5311439160633c /arch/powerpc/kernel/idle_power4.S
parent183b73ae7c9e4e19fa95d88e1778481899a65210 (diff)
powerpc: Use correct sequence for putting CPU into nap mode
We weren't using the recommended sequence for putting the CPU into nap mode. When I changed the idle loop, for some reason 7447A cpus started hanging when we put them into nap mode. Changing to the recommended sequence fixes that. The complexity here is that the recommended sequence is a loop that keeps putting the cpu back into nap mode. Clearly we need some way to break out of the loop when an interrupt (external interrupt, decrementer, performance monitor) occurs. Here we use a bit in the thread_info struct to indicate that we need this, and the exception entry code notices this and arranges for the exception to return to the value in the link register, thus breaking out of the loop. We use a new `local_flags' field in the thread_info which we can alter without needing to use an atomic update sequence. The PPC970 has the same recommended sequence, so we do the same thing there too. This also fixes a bug in the kernel stack overflow handling code on 32-bit, since it was causing a value that we needed in a register to get trashed. Signed-off-by: Paul Mackerras <paulus@samba.org>
Diffstat (limited to 'arch/powerpc/kernel/idle_power4.S')
-rw-r--r--arch/powerpc/kernel/idle_power4.S10
1 files changed, 7 insertions, 3 deletions
diff --git a/arch/powerpc/kernel/idle_power4.S b/arch/powerpc/kernel/idle_power4.S
index 6dad1c02496e..d85c7c938eed 100644
--- a/arch/powerpc/kernel/idle_power4.S
+++ b/arch/powerpc/kernel/idle_power4.S
@@ -35,12 +35,16 @@ BEGIN_FTR_SECTION
35 DSSALL 35 DSSALL
36 sync 36 sync
37END_FTR_SECTION_IFSET(CPU_FTR_ALTIVEC) 37END_FTR_SECTION_IFSET(CPU_FTR_ALTIVEC)
38 clrrdi r9,r1,THREAD_SHIFT /* current thread_info */
39 ld r8,TI_LOCAL_FLAGS(r9) /* set napping bit */
40 ori r8,r8,_TLF_NAPPING /* so when we take an exception */
41 std r8,TI_LOCAL_FLAGS(r9) /* it will return to our caller */
38 mfmsr r7 42 mfmsr r7
39 ori r7,r7,MSR_EE 43 ori r7,r7,MSR_EE
40 oris r7,r7,MSR_POW@h 44 oris r7,r7,MSR_POW@h
41 sync 451: sync
42 isync 46 isync
43 mtmsrd r7 47 mtmsrd r7
44 isync 48 isync
45 sync 49 b 1b
46 blr 50