aboutsummaryrefslogtreecommitdiffstats
path: root/arch/arm64
diff options
context:
space:
mode:
authorAndre Przywara <andre.przywara@arm.com>2014-11-14 10:54:11 -0500
committerWill Deacon <will.deacon@arm.com>2014-11-25 10:56:42 -0500
commit5afaa1fc1b320cec48affa7e6949f2493f875c12 (patch)
tree6d7d20ce61c2939548c6b5105bc5130c4f7191ac /arch/arm64
parent301bcfac42897dbd1b0b3c1be49f24654a1bc49e (diff)
arm64: add Cortex-A57 erratum 832075 workaround
The ARM erratum 832075 applies to certain revisions of Cortex-A57, one of the workarounds is to change device loads into using load-aquire semantics. This is achieved using the alternatives framework. Signed-off-by: Andre Przywara <andre.przywara@arm.com> Signed-off-by: Will Deacon <will.deacon@arm.com>
Diffstat (limited to 'arch/arm64')
-rw-r--r--arch/arm64/include/asm/cpufeature.h5
-rw-r--r--arch/arm64/include/asm/io.h23
-rw-r--r--arch/arm64/kernel/cpu_errata.c7
3 files changed, 29 insertions, 6 deletions
diff --git a/arch/arm64/include/asm/cpufeature.h b/arch/arm64/include/asm/cpufeature.h
index 92b6ee44669b..0362f8020d46 100644
--- a/arch/arm64/include/asm/cpufeature.h
+++ b/arch/arm64/include/asm/cpufeature.h
@@ -21,9 +21,10 @@
21#define MAX_CPU_FEATURES (8 * sizeof(elf_hwcap)) 21#define MAX_CPU_FEATURES (8 * sizeof(elf_hwcap))
22#define cpu_feature(x) ilog2(HWCAP_ ## x) 22#define cpu_feature(x) ilog2(HWCAP_ ## x)
23 23
24#define ARM64_WORKAROUND_CLEAN_CACHE 0 24#define ARM64_WORKAROUND_CLEAN_CACHE 0
25#define ARM64_WORKAROUND_DEVICE_LOAD_ACQUIRE 1
25 26
26#define NCAPS 1 27#define NCAPS 2
27 28
28#ifndef __ASSEMBLY__ 29#ifndef __ASSEMBLY__
29 30
diff --git a/arch/arm64/include/asm/io.h b/arch/arm64/include/asm/io.h
index 79f1d519221f..75825b63464d 100644
--- a/arch/arm64/include/asm/io.h
+++ b/arch/arm64/include/asm/io.h
@@ -28,6 +28,8 @@
28#include <asm/barrier.h> 28#include <asm/barrier.h>
29#include <asm/pgtable.h> 29#include <asm/pgtable.h>
30#include <asm/early_ioremap.h> 30#include <asm/early_ioremap.h>
31#include <asm/alternative.h>
32#include <asm/cpufeature.h>
31 33
32#include <xen/xen.h> 34#include <xen/xen.h>
33 35
@@ -57,28 +59,41 @@ static inline void __raw_writeq(u64 val, volatile void __iomem *addr)
57static inline u8 __raw_readb(const volatile void __iomem *addr) 59static inline u8 __raw_readb(const volatile void __iomem *addr)
58{ 60{
59 u8 val; 61 u8 val;
60 asm volatile("ldrb %w0, [%1]" : "=r" (val) : "r" (addr)); 62 asm volatile(ALTERNATIVE("ldrb %w0, [%1]",
63 "ldarb %w0, [%1]",
64 ARM64_WORKAROUND_DEVICE_LOAD_ACQUIRE)
65 : "=r" (val) : "r" (addr));
61 return val; 66 return val;
62} 67}
63 68
64static inline u16 __raw_readw(const volatile void __iomem *addr) 69static inline u16 __raw_readw(const volatile void __iomem *addr)
65{ 70{
66 u16 val; 71 u16 val;
67 asm volatile("ldrh %w0, [%1]" : "=r" (val) : "r" (addr)); 72
73 asm volatile(ALTERNATIVE("ldrh %w0, [%1]",
74 "ldarh %w0, [%1]",
75 ARM64_WORKAROUND_DEVICE_LOAD_ACQUIRE)
76 : "=r" (val) : "r" (addr));
68 return val; 77 return val;
69} 78}
70 79
71static inline u32 __raw_readl(const volatile void __iomem *addr) 80static inline u32 __raw_readl(const volatile void __iomem *addr)
72{ 81{
73 u32 val; 82 u32 val;
74 asm volatile("ldr %w0, [%1]" : "=r" (val) : "r" (addr)); 83 asm volatile(ALTERNATIVE("ldr %w0, [%1]",
84 "ldar %w0, [%1]",
85 ARM64_WORKAROUND_DEVICE_LOAD_ACQUIRE)
86 : "=r" (val) : "r" (addr));
75 return val; 87 return val;
76} 88}
77 89
78static inline u64 __raw_readq(const volatile void __iomem *addr) 90static inline u64 __raw_readq(const volatile void __iomem *addr)
79{ 91{
80 u64 val; 92 u64 val;
81 asm volatile("ldr %0, [%1]" : "=r" (val) : "r" (addr)); 93 asm volatile(ALTERNATIVE("ldr %0, [%1]",
94 "ldar %0, [%1]",
95 ARM64_WORKAROUND_DEVICE_LOAD_ACQUIRE)
96 : "=r" (val) : "r" (addr));
82 return val; 97 return val;
83} 98}
84 99
diff --git a/arch/arm64/kernel/cpu_errata.c b/arch/arm64/kernel/cpu_errata.c
index e107ed2d66dc..30935d2da55a 100644
--- a/arch/arm64/kernel/cpu_errata.c
+++ b/arch/arm64/kernel/cpu_errata.c
@@ -24,6 +24,7 @@
24#include <asm/cpufeature.h> 24#include <asm/cpufeature.h>
25 25
26#define MIDR_CORTEX_A53 MIDR_CPU_PART(ARM_CPU_IMP_ARM, ARM_CPU_PART_CORTEX_A53) 26#define MIDR_CORTEX_A53 MIDR_CPU_PART(ARM_CPU_IMP_ARM, ARM_CPU_PART_CORTEX_A53)
27#define MIDR_CORTEX_A57 MIDR_CPU_PART(ARM_CPU_IMP_ARM, ARM_CPU_PART_CORTEX_A57)
27 28
28/* 29/*
29 * Add a struct or another datatype to the union below if you need 30 * Add a struct or another datatype to the union below if you need
@@ -71,6 +72,12 @@ struct arm64_cpu_capabilities arm64_errata[] = {
71 MIDR_RANGE(MIDR_CORTEX_A53, 0x00, 0x02), 72 MIDR_RANGE(MIDR_CORTEX_A53, 0x00, 0x02),
72 }, 73 },
73 { 74 {
75 /* Cortex-A57 r0p0 - r1p2 */
76 .desc = "ARM erratum 832075",
77 .capability = ARM64_WORKAROUND_DEVICE_LOAD_ACQUIRE,
78 MIDR_RANGE(MIDR_CORTEX_A57, 0x00, 0x12),
79 },
80 {
74 } 81 }
75}; 82};
76 83