summary refs log tree commit diff
path: root/arch
diff options
context:
space:
mode:
authorDimitry Andric <dimitry@andric.com>2006-05-17 16:31:11 +0100
committerRussell King <rmk+kernel@arm.linux.org.uk>2006-05-17 16:31:11 +0100
commitc3fb04162a1c8ddcf6caa6e19020da3f0fd23103 (patch)
tree235f4fbd8f90e07092ca6ece9d544072fcd5246e /arch
parent0c056c50a6218e0e577817c16ba8851af593d742 (diff)
downloadlinux-c3fb04162a1c8ddcf6caa6e19020da3f0fd23103.tar.gz
[ARM] 3529/1: s3c24xx: fix restoring control register with undefined instruction
Patch from Dimitry Andric

In arch/arm/mach-s3c2410/sleep.S, the coprocessor registers are saved at
suspend time, and restored at resume time. However, an undefined
instruction is used when attempting to restore a non-existent "auxiliary
control register".  This leads to a crash on S3C2412, which has an ARM926
core instead of an ARM920.

At suspend time, the following fragment runs:

	mrc	p15, 0, r7, c2, c0, 0	@ translation table base address
	mrc	p15, 0, r8, c2, c0, 0	@ auxiliary control register
	mrc	p15, 0, r9, c1, c0, 0	@ control register

and at resume time, the following fragment runs:

	mcr	p15, 0, r7, c2, c0, 0		@ translation table base
	mcr	p15, 0, r8, c1, c1, 0		@ auxilliary control
	...
	mcr	p15, 0, r9, c1, c0, 0		@ turn on MMU, etc

There are several problems with these fragments:
1. The ARM920 and ARM926 cores don't have any "auxiliary control
   register", at least not according to the ARM920 and ARM926 TRM's.
2. The 2nd line of suspend erroneously saves the c2 register again.
3. This saved c2 value is restored using an undefined instruction.  For
   some reason this does not crash on ARM920, but does crash on ARM926.

The following patch fixes all these problems.

Signed-off-by: Dimitry Andric <dimitry@andric.com>
Yes, this looks sensible

Signed-off-by: Ben Dooks <ben-linux@fluff.org>
Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
Diffstat (limited to 'arch')
-rw-r--r--arch/arm/mach-s3c2410/sleep.S6
1 files changed, 2 insertions, 4 deletions
diff --git a/arch/arm/mach-s3c2410/sleep.S b/arch/arm/mach-s3c2410/sleep.S
index 832fb86a03b4..73de2eaca22a 100644
--- a/arch/arm/mach-s3c2410/sleep.S
+++ b/arch/arm/mach-s3c2410/sleep.S
@@ -59,8 +59,7 @@ ENTRY(s3c2410_cpu_suspend)
 	mrc	p15, 0, r5, c13, c0, 0	@ PID
 	mrc	p15, 0, r6, c3, c0, 0	@ Domain ID
 	mrc	p15, 0, r7, c2, c0, 0	@ translation table base address
-	mrc	p15, 0, r8, c2, c0, 0	@ auxiliary control register
-	mrc	p15, 0, r9, c1, c0, 0	@ control register
+	mrc	p15, 0, r8, c1, c0, 0	@ control register
 
 	stmia	r0, { r4 - r13 }
 
@@ -165,7 +164,6 @@ ENTRY(s3c2410_cpu_resume)
 	mcr	p15, 0, r5, c13, c0, 0		@ PID
 	mcr	p15, 0, r6, c3, c0, 0		@ Domain ID
 	mcr	p15, 0, r7, c2, c0, 0		@ translation table base
-	mcr	p15, 0, r8, c1, c1, 0		@ auxilliary control
 
 #ifdef CONFIG_DEBUG_RESUME
 	mov	r3, #'R'
@@ -173,7 +171,7 @@ ENTRY(s3c2410_cpu_resume)
 #endif
 
 	ldr	r2, =resume_with_mmu
-	mcr	p15, 0, r9, c1, c0, 0		@ turn on MMU, etc
+	mcr	p15, 0, r8, c1, c0, 0		@ turn on MMU, etc
 	nop					@ second-to-last before mmu
 	mov	pc, r2				@ go back to virtual address