From 9e5b2debe12d4e840a7d3ec0cf22b215396ed46e Mon Sep 17 00:00:00 2001
From: Phil Elwell <phil@raspberrypi.com>
Date: Wed, 29 Jul 2020 13:47:55 +0100
Subject: [PATCH] ARM: proc-v7: Force misalignment of early stmia

In an attempt to prevent the problem of CPUn not starting, explicitly
misalign the scratch space used to save registers acros the cache
invalidation.

Notes:
At this stage in the boot process the core is running with its cache
disabled. Before enabling the cache its contents must be explicitly
invalidated, a process that requires quite a few registers that the
caller must preserve. Evidence suggests that something is writing a
block of zeroes over that space at a time when all other cores should
be idle, possibly some kind of write-combiner, and the misalignment is
designed to disrupt any write-coalescing.

In truth, I don't understand why this patch works, and when the failure
is so random it is hard to be certain that this isn't just rolling the
dice again. One interesting test would be to change the "addeq r12, #4"s
to "addeq r12, #0"s determine see if the offset itself is significant or
just the additional code.

See: https://github.com/Hexxeh/rpi-firmware/issues/232

Signed-off-by: Phil Elwell <phil@raspberrypi.com>
---
 arch/arm/mm/proc-v7.S | 6 +++++-
 1 file changed, 5 insertions(+), 1 deletion(-)

--- a/arch/arm/mm/proc-v7.S
+++ b/arch/arm/mm/proc-v7.S
@@ -287,6 +287,8 @@ __v7_ca17mp_setup:
 	mov	r10, #0
 1:	adr	r0, __v7_setup_stack_ptr
 	ldr	r12, [r0]
+	tst	r12, #0x1f
+	addeq	r12, r12, #4
 	add	r12, r12, r0			@ the local stack
 	stmia	r12, {r1-r6, lr}		@ v7_invalidate_l1 touches r0-r6
 	bl      v7_invalidate_l1
@@ -474,6 +476,8 @@ __v7_setup:
 	adr	r0, __v7_setup_stack_ptr
 	ldr	r12, [r0]
 	add	r12, r12, r0			@ the local stack
+	tst	r12, #0x1f
+	addeq	r12, r12, #4
 	stmia	r12, {r1-r6, lr}		@ v7_invalidate_l1 touches r0-r6
 	bl      v7_invalidate_l1
 	ldmia	r12, {r1-r6, lr}
@@ -557,7 +561,7 @@ ENDPROC(__v7_setup)
 	.bss
 	.align	2
 __v7_setup_stack:
-	.space	4 * 7				@ 7 registers
+	.space	4 * 8				@ 7 registers + 1 spare
 
 	__INITDATA
 
