BACKPORT: FROMLIST: ARM: errata: Workaround errata A12 818325/852422 A17 852423

There are several similar errata on Cortex A12 and A17 that all have the
same workaround: setting bit[12] of the Feature Register.  Technically
the list of errata are:

- A12 818325: Execution of an UNPREDICTABLE STR or STM instruction might
  deadlock.  Fixed in r0p1.
- A12 852422: Execution of a sequence of instructions might lead to
  either a data corruption or a CPU deadlock.  Not fixed in any A12s
  yet.
- A17 852423: Execution of a sequence of instructions might lead to
  either a data corruption or a CPU deadlock.  Not fixed in any A17s
  yet.

Since A12 got renamed to A17 it seems likely that there won't be any
future Cortex-A12 cores, so we'll enable for all Cortex-A12.

For Cortex-A17 I believe that all known revisions are affected and that
all knows revisions means <= r1p2.  Presumably if a new A17 was released
it would have this problem fixed.

Note that in <https://patchwork.kernel.org/patch/4735341/> folks
previously expressed opposition to this change because:
A) It was thought to only apply to r0p0 and there were no known r0p0
   boards supported in mainline.
B) It was argued that such a workaround beloned in firmware.

Now that this same fix solves other errata on real boards (like rk3288)
point A) is addressed.

Point B) is impossible to address on boards like rk3288.  On rk3288 the
firmware doesn't stay resident in RAM and isn't involved at all in the
suspend/resume process nor in the SMP bringup process.  That means that
the most the firmware could do would be to set the bit on "core 0" and
this bit would be lost at suspend/resume time.  It is true that we could
write a "generic" solution that saved the boot-time "core 0" value of
this register and applied it at SMP bringup / resume time.  However,
since this register (described as the "Feature Register" in errata)
appears to be undocumented (as far as I can tell) and is only modified
for these errata, that "generic" solution seems questionably cleaner.
The generic solution also won't fix existing users that haven't happened
to do a FW update.

Note that in ARM64 presumably PSCI will be universal and fixes like this
will end up in ATF.  Hopefully we are nearing the end of this style of
errata workaround.

BUG=chrome-os-partner:50137
TEST=CL:If49e61d7825bdfaf0eb3664c42aa9b0ba2fe66b2

Conflicts:
	arch/arm/mm/proc-v7.S
...due to massive re-org upstream that doesn't make sense to pick back.
Note also that while backporting I fixed a few random bugs where we
would apply errata to cores not manufactured by ARM and optimized the
jumps a bit for A8 / A9.  These types of issues have already been fixed
by the reorg upstream.

Change-Id: Id0ecbb83b8da159237d75a33bab82dd4677740c3
Signed-off-by: Douglas Anderson <dianders@chromium.org>
Signed-off-by: Huang Tao <huangtao@rock-chips.com>
Signed-off-by: Kever Yang <kever.yang@rock-chips.com>
(am from https://patchwork.kernel.org/patch/8441441/)
Reviewed-on: https://chromium-review.googlesource.com/329521
Reviewed-by: Olof Johansson <olofj@chromium.org>

(cherry picked from commit 2498b98fd7946175016af8edde72059d58405ae7)
This commit is contained in:
Douglas Anderson
2016-02-26 11:20:59 -08:00
committed by Chris Zhong
parent a7ce3801d4
commit ed65feb600
2 changed files with 51 additions and 27 deletions

View File

@@ -1378,19 +1378,32 @@ config ARM_ERRATA_773022
loop buffer may deliver incorrect instructions. This
workaround disables the loop buffer to avoid the erratum.
config ARM_ERRATA_818325
bool "ARM errata: Execution of an UNPREDICTABLE STR or STM instruction might deadlock"
config ARM_ERRATA_818325_852422
bool "ARM errata: A12: some seqs of opposed cond code instrs => deadlock or corruption"
depends on CPU_V7
help
This option enables the workaround for the 818325 Cortex-A12
(r0p0..r0p1-00lac0-rc11) erratum. When a CPU executes a sequence of
two conditional store instructions with opposite condition code and
updating the same register, the system might enter a deadlock if the
second conditional instruction is an UNPREDICTABLE STR or STM
instruction. This workaround setting bit[12] of the Feature Register
prevents the erratum. This bit disables an optimisation applied to a
This option enables the workaround for:
- Cortex-A12 818325: Execution of an UNPREDICTABLE STR or STM
instruction might deadlock. Fixed in r0p1.
- Cortex-A12 852422: Execution of a sequence of instructions might
lead to either a data corruption or a CPU deadlock. Not fixed in
any Cortex-A12 cores yet.
This workaround for all both errata involves setting bit[12] of the
Feature Register. This bit disables an optimisation applied to a
sequence of 2 instructions that use opposing condition codes.
config ARM_ERRATA_852423
bool "ARM errata: A17: some seqs of opposed cond code instrs => deadlock or corruption"
depends on CPU_V7
help
This option enables the workaround for:
- Cortex-A17 852423: Execution of a sequence of instructions might
lead to either a data corruption or a CPU deadlock. Not fixed in
any Cortex-A17 cores yet.
This is identical to Cortex-A12 erratum 852422. It is a separate
config option from the A12 erratum due to the way errata are checked
for and handled.
endmenu
source "arch/arm/common/Kconfig"

View File

@@ -271,7 +271,7 @@ __v7_setup:
mrc p15, 0, r0, c0, c0, 0 @ read main ID register
and r10, r0, #0xff000000 @ ARM?
teq r10, #0x41000000
bne 3f
bne 6f
and r5, r0, #0x00f00000 @ variant
and r6, r0, #0x0000000f @ revision
orr r6, r6, r5, lsr #20-4 @ combine variant and revision
@@ -302,7 +302,7 @@ __v7_setup:
orreq r10, r10, #(1 << 22) @ set the Write Allocate disable bit
mcreq p15, 1, r10, c9, c0, 2 @ write the L2 cache aux ctrl register
#endif
b 3f
b 6f
/* Cortex-A9 Errata */
2: ldr r10, =0x00000c09 @ Cortex-A9 primary part number
@@ -337,11 +337,35 @@ __v7_setup:
mcrlt p15, 0, r10, c15, c0, 1 @ write diagnostic register
1:
#endif
b 6f
/* Cortex-A15 Errata */
3: ldr r10, =0x00000c0f @ Cortex-A15 primary part number
/* Cortex-A12 Errata */
3: ldr r10, =0x00000c0d @ Cortex-A12 primary part number
teq r0, r10
bne 4f
#ifdef CONFIG_ARM_ERRATA_818325_852422
mrc p15, 0, r10, c15, c0, 1 @ read diagnostic register
orr r10, r10, #1 << 12 @ set bit #12
mcr p15, 0, r10, c15, c0, 1 @ write diagnostic register
#endif
b 6f
/* Cortex-A17 Errata */
4: ldr r10, =0x00000c0e @ Cortex-A17 primary part number
teq r0, r10
bne 5f
#ifdef CONFIG_ARM_ERRATA_852423
cmp r6, #0x12 @ only present up to r1p2
mrcle p15, 0, r10, c15, c0, 1 @ read diagnostic register
orrle r10, r10, #1 << 12 @ set bit #12
mcrle p15, 0, r10, c15, c0, 1 @ write diagnostic register
#endif
b 6f
/* Cortex-A15 Errata */
5: ldr r10, =0x00000c0f @ Cortex-A15 primary part number
teq r0, r10
bne 6f
#ifdef CONFIG_ARM_ERRATA_773022
cmp r6, #0x4 @ only present up to r0p4
@@ -350,20 +374,7 @@ __v7_setup:
mcrle p15, 0, r10, c1, c0, 1 @ write aux control register
#endif
/* Cortex-A12 Errata */
4: ldr r10, =0x00000c0d @ Cortex-A12 primary part number
teq r0, r10
bne 5f
#ifdef CONFIG_ARM_ERRATA_818325
teq r6, #0x00 @ present in r0p0
teqne r6, #0x01 @ present in r0p1-00lac0-rc11
mrceq p15, 0, r10, c15, c0, 1 @ read diagnostic register
orreq r10, r10, #1 << 12 @ set bit #12
mcreq p15, 0, r10, c15, c0, 1 @ write diagnostic register
isb
#endif
5: mov r10, #0
6: mov r10, #0
mcr p15, 0, r10, c7, c5, 0 @ I+BTB cache invalidate
#ifdef CONFIG_MMU
mcr p15, 0, r10, c8, c7, 0 @ invalidate I + D TLBs