aboutsummaryrefslogtreecommitdiffstats
path: root/arch/arm/include
diff options
context:
space:
mode:
authorDavid Howells <dhowells@redhat.com>2012-03-28 13:30:01 -0400
committerDavid Howells <dhowells@redhat.com>2012-03-28 13:30:01 -0400
commit9f97da78bf018206fb623cd351d454af2f105fe0 (patch)
tree509971bf0d93f56d7ad182bdad3c89886f7ce675 /arch/arm/include
parent15d07dc9c59eae51219c40253bdf920f62bb10f2 (diff)
Disintegrate asm/system.h for ARM
Disintegrate asm/system.h for ARM. Signed-off-by: David Howells <dhowells@redhat.com> cc: Russell King <linux@arm.linux.org.uk> cc: linux-arm-kernel@lists.infradead.org
Diffstat (limited to 'arch/arm/include')
-rw-r--r--arch/arm/include/asm/atomic.h4
-rw-r--r--arch/arm/include/asm/barrier.h69
-rw-r--r--arch/arm/include/asm/bitops.h2
-rw-r--r--arch/arm/include/asm/bug.h30
-rw-r--r--arch/arm/include/asm/cmpxchg.h295
-rw-r--r--arch/arm/include/asm/compiler.h15
-rw-r--r--arch/arm/include/asm/cp15.h2
-rw-r--r--arch/arm/include/asm/div64.h2
-rw-r--r--arch/arm/include/asm/dma.h1
-rw-r--r--arch/arm/include/asm/domain.h4
-rw-r--r--arch/arm/include/asm/exec.h6
-rw-r--r--arch/arm/include/asm/io.h2
-rw-r--r--arch/arm/include/asm/mmu.h7
-rw-r--r--arch/arm/include/asm/processor.h3
-rw-r--r--arch/arm/include/asm/switch_to.h18
-rw-r--r--arch/arm/include/asm/system.h474
-rw-r--r--arch/arm/include/asm/system_info.h27
-rw-r--r--arch/arm/include/asm/system_misc.h28
-rw-r--r--arch/arm/include/asm/uaccess.h2
19 files changed, 517 insertions, 474 deletions
diff --git a/arch/arm/include/asm/atomic.h b/arch/arm/include/asm/atomic.h
index 86976d03438..68374ba6a94 100644
--- a/arch/arm/include/asm/atomic.h
+++ b/arch/arm/include/asm/atomic.h
@@ -13,7 +13,9 @@
13 13
14#include <linux/compiler.h> 14#include <linux/compiler.h>
15#include <linux/types.h> 15#include <linux/types.h>
16#include <asm/system.h> 16#include <linux/irqflags.h>
17#include <asm/barrier.h>
18#include <asm/cmpxchg.h>
17 19
18#define ATOMIC_INIT(i) { (i) } 20#define ATOMIC_INIT(i) { (i) }
19 21
diff --git a/arch/arm/include/asm/barrier.h b/arch/arm/include/asm/barrier.h
new file mode 100644
index 00000000000..44f4a09ff37
--- /dev/null
+++ b/arch/arm/include/asm/barrier.h
@@ -0,0 +1,69 @@
1#ifndef __ASM_BARRIER_H
2#define __ASM_BARRIER_H
3
4#ifndef __ASSEMBLY__
5
6#define nop() __asm__ __volatile__("mov\tr0,r0\t@ nop\n\t");
7
8#if __LINUX_ARM_ARCH__ >= 7 || \
9 (__LINUX_ARM_ARCH__ == 6 && defined(CONFIG_CPU_32v6K))
10#define sev() __asm__ __volatile__ ("sev" : : : "memory")
11#define wfe() __asm__ __volatile__ ("wfe" : : : "memory")
12#define wfi() __asm__ __volatile__ ("wfi" : : : "memory")
13#endif
14
15#if __LINUX_ARM_ARCH__ >= 7
16#define isb() __asm__ __volatile__ ("isb" : : : "memory")
17#define dsb() __asm__ __volatile__ ("dsb" : : : "memory")
18#define dmb() __asm__ __volatile__ ("dmb" : : : "memory")
19#elif defined(CONFIG_CPU_XSC3) || __LINUX_ARM_ARCH__ == 6
20#define isb() __asm__ __volatile__ ("mcr p15, 0, %0, c7, c5, 4" \
21 : : "r" (0) : "memory")
22#define dsb() __asm__ __volatile__ ("mcr p15, 0, %0, c7, c10, 4" \
23 : : "r" (0) : "memory")
24#define dmb() __asm__ __volatile__ ("mcr p15, 0, %0, c7, c10, 5" \
25 : : "r" (0) : "memory")
26#elif defined(CONFIG_CPU_FA526)
27#define isb() __asm__ __volatile__ ("mcr p15, 0, %0, c7, c5, 4" \
28 : : "r" (0) : "memory")
29#define dsb() __asm__ __volatile__ ("mcr p15, 0, %0, c7, c10, 4" \
30 : : "r" (0) : "memory")
31#define dmb() __asm__ __volatile__ ("" : : : "memory")
32#else
33#define isb() __asm__ __volatile__ ("" : : : "memory")
34#define dsb() __asm__ __volatile__ ("mcr p15, 0, %0, c7, c10, 4" \
35 : : "r" (0) : "memory")
36#define dmb() __asm__ __volatile__ ("" : : : "memory")
37#endif
38
39#ifdef CONFIG_ARCH_HAS_BARRIERS
40#include <mach/barriers.h>
41#elif defined(CONFIG_ARM_DMA_MEM_BUFFERABLE) || defined(CONFIG_SMP)
42#include <asm/outercache.h>
43#define mb() do { dsb(); outer_sync(); } while (0)
44#define rmb() dsb()
45#define wmb() mb()
46#else
47#include <asm/memory.h>
48#define mb() do { if (arch_is_coherent()) dmb(); else barrier(); } while (0)
49#define rmb() do { if (arch_is_coherent()) dmb(); else barrier(); } while (0)
50#define wmb() do { if (arch_is_coherent()) dmb(); else barrier(); } while (0)
51#endif
52
53#ifndef CONFIG_SMP
54#define smp_mb() barrier()
55#define smp_rmb() barrier()
56#define smp_wmb() barrier()
57#else
58#define smp_mb() dmb()
59#define smp_rmb() dmb()
60#define smp_wmb() dmb()
61#endif
62
63#define read_barrier_depends() do { } while(0)
64#define smp_read_barrier_depends() do { } while(0)
65
66#define set_mb(var, value) do { var = value; smp_mb(); } while (0)
67
68#endif /* !__ASSEMBLY__ */
69#endif /* __ASM_BARRIER_H */
diff --git a/arch/arm/include/asm/bitops.h b/arch/arm/include/asm/bitops.h
index f7419ef9c8f..e691ec91e4d 100644
--- a/arch/arm/include/asm/bitops.h
+++ b/arch/arm/include/asm/bitops.h
@@ -24,7 +24,7 @@
24#endif 24#endif
25 25
26#include <linux/compiler.h> 26#include <linux/compiler.h>
27#include <asm/system.h> 27#include <linux/irqflags.h>
28 28
29#define smp_mb__before_clear_bit() smp_mb() 29#define smp_mb__before_clear_bit() smp_mb()
30#define smp_mb__after_clear_bit() smp_mb() 30#define smp_mb__after_clear_bit() smp_mb()
diff --git a/arch/arm/include/asm/bug.h b/arch/arm/include/asm/bug.h
index fac79dceb73..7af5c6c3653 100644
--- a/arch/arm/include/asm/bug.h
+++ b/arch/arm/include/asm/bug.h
@@ -1,6 +1,7 @@
1#ifndef _ASMARM_BUG_H 1#ifndef _ASMARM_BUG_H
2#define _ASMARM_BUG_H 2#define _ASMARM_BUG_H
3 3
4#include <linux/linkage.h>
4 5
5#ifdef CONFIG_BUG 6#ifdef CONFIG_BUG
6 7
@@ -57,4 +58,33 @@ do { \
57 58
58#include <asm-generic/bug.h> 59#include <asm-generic/bug.h>
59 60
61struct pt_regs;
62void die(const char *msg, struct pt_regs *regs, int err);
63
64struct siginfo;
65void arm_notify_die(const char *str, struct pt_regs *regs, struct siginfo *info,
66 unsigned long err, unsigned long trap);
67
68#ifdef CONFIG_ARM_LPAE
69#define FAULT_CODE_ALIGNMENT 33
70#define FAULT_CODE_DEBUG 34
71#else
72#define FAULT_CODE_ALIGNMENT 1
73#define FAULT_CODE_DEBUG 2
74#endif
75
76void hook_fault_code(int nr, int (*fn)(unsigned long, unsigned int,
77 struct pt_regs *),
78 int sig, int code, const char *name);
79
80void hook_ifault_code(int nr, int (*fn)(unsigned long, unsigned int,
81 struct pt_regs *),
82 int sig, int code, const char *name);
83
84extern asmlinkage void c_backtrace(unsigned long fp, int pmode);
85
86struct mm_struct;
87extern void show_pte(struct mm_struct *mm, unsigned long addr);
88extern void __show_regs(struct pt_regs *);
89
60#endif 90#endif
diff --git a/arch/arm/include/asm/cmpxchg.h b/arch/arm/include/asm/cmpxchg.h
new file mode 100644
index 00000000000..d41d7cbf0ad
--- /dev/null
+++ b/arch/arm/include/asm/cmpxchg.h
@@ -0,0 +1,295 @@
1#ifndef __ASM_ARM_CMPXCHG_H
2#define __ASM_ARM_CMPXCHG_H
3
4#include <linux/irqflags.h>
5#include <asm/barrier.h>
6
7#if defined(CONFIG_CPU_SA1100) || defined(CONFIG_CPU_SA110)
8/*
9 * On the StrongARM, "swp" is terminally broken since it bypasses the
10 * cache totally. This means that the cache becomes inconsistent, and,
11 * since we use normal loads/stores as well, this is really bad.
12 * Typically, this causes oopsen in filp_close, but could have other,
13 * more disastrous effects. There are two work-arounds:
14 * 1. Disable interrupts and emulate the atomic swap
15 * 2. Clean the cache, perform atomic swap, flush the cache
16 *
17 * We choose (1) since its the "easiest" to achieve here and is not
18 * dependent on the processor type.
19 *
20 * NOTE that this solution won't work on an SMP system, so explcitly
21 * forbid it here.
22 */
23#define swp_is_buggy
24#endif
25
26static inline unsigned long __xchg(unsigned long x, volatile void *ptr, int size)
27{
28 extern void __bad_xchg(volatile void *, int);
29 unsigned long ret;
30#ifdef swp_is_buggy
31 unsigned long flags;
32#endif
33#if __LINUX_ARM_ARCH__ >= 6
34 unsigned int tmp;
35#endif
36
37 smp_mb();
38
39 switch (size) {
40#if __LINUX_ARM_ARCH__ >= 6
41 case 1:
42 asm volatile("@ __xchg1\n"
43 "1: ldrexb %0, [%3]\n"
44 " strexb %1, %2, [%3]\n"
45 " teq %1, #0\n"
46 " bne 1b"
47 : "=&r" (ret), "=&r" (tmp)
48 : "r" (x), "r" (ptr)
49 : "memory", "cc");
50 break;
51 case 4:
52 asm volatile("@ __xchg4\n"
53 "1: ldrex %0, [%3]\n"
54 " strex %1, %2, [%3]\n"
55 " teq %1, #0\n"
56 " bne 1b"
57 : "=&r" (ret), "=&r" (tmp)
58 : "r" (x), "r" (ptr)
59 : "memory", "cc");
60 break;
61#elif defined(swp_is_buggy)
62#ifdef CONFIG_SMP
63#error SMP is not supported on this platform
64#endif
65 case 1:
66 raw_local_irq_save(flags);
67 ret = *(volatile unsigned char *)ptr;
68 *(volatile unsigned char *)ptr = x;
69 raw_local_irq_restore(flags);
70 break;
71
72 case 4:
73 raw_local_irq_save(flags);
74 ret = *(volatile unsigned long *)ptr;
75 *(volatile unsigned long *)ptr = x;
76 raw_local_irq_restore(flags);
77 break;
78#else
79 case 1:
80 asm volatile("@ __xchg1\n"
81 " swpb %0, %1, [%2]"
82 : "=&r" (ret)
83 : "r" (x), "r" (ptr)
84 : "memory", "cc");
85 break;
86 case 4:
87 asm volatile("@ __xchg4\n"
88 " swp %0, %1, [%2]"
89 : "=&r" (ret)
90 : "r" (x), "r" (ptr)
91 : "memory", "cc");
92 break;
93#endif
94 default:
95 __bad_xchg(ptr, size), ret = 0;
96 break;
97 }
98 smp_mb();
99
100 return ret;
101}
102
103#define xchg(ptr,x) \
104 ((__typeof__(*(ptr)))__xchg((unsigned long)(x),(ptr),sizeof(*(ptr))))
105
106#include <asm-generic/cmpxchg-local.h>
107
108#if __LINUX_ARM_ARCH__ < 6
109/* min ARCH < ARMv6 */
110
111#ifdef CONFIG_SMP
112#error "SMP is not supported on this platform"
113#endif
114
115/*
116 * cmpxchg_local and cmpxchg64_local are atomic wrt current CPU. Always make
117 * them available.
118 */
119#define cmpxchg_local(ptr, o, n) \
120 ((__typeof__(*(ptr)))__cmpxchg_local_generic((ptr), (unsigned long)(o),\
121 (unsigned long)(n), sizeof(*(ptr))))
122#define cmpxchg64_local(ptr, o, n) __cmpxchg64_local_generic((ptr), (o), (n))
123
124#ifndef CONFIG_SMP
125#include <asm-generic/cmpxchg.h>
126#endif
127
128#else /* min ARCH >= ARMv6 */
129
130extern void __bad_cmpxchg(volatile void *ptr, int size);
131
132/*
133 * cmpxchg only support 32-bits operands on ARMv6.
134 */
135
136static inline unsigned long __cmpxchg(volatile void *ptr, unsigned long old,
137 unsigned long new, int size)
138{
139 unsigned long oldval, res;
140
141 switch (size) {
142#ifndef CONFIG_CPU_V6 /* min ARCH >= ARMv6K */
143 case 1:
144 do {
145 asm volatile("@ __cmpxchg1\n"
146 " ldrexb %1, [%2]\n"
147 " mov %0, #0\n"
148 " teq %1, %3\n"
149 " strexbeq %0, %4, [%2]\n"
150 : "=&r" (res), "=&r" (oldval)
151 : "r" (ptr), "Ir" (old), "r" (new)
152 : "memory", "cc");
153 } while (res);
154 break;
155 case 2:
156 do {
157 asm volatile("@ __cmpxchg1\n"
158 " ldrexh %1, [%2]\n"
159 " mov %0, #0\n"
160 " teq %1, %3\n"
161 " strexheq %0, %4, [%2]\n"
162 : "=&r" (res), "=&r" (oldval)
163 : "r" (ptr), "Ir" (old), "r" (new)
164 : "memory", "cc");
165 } while (res);
166 break;
167#endif
168 case 4:
169 do {
170 asm volatile("@ __cmpxchg4\n"
171 " ldrex %1, [%2]\n"
172 " mov %0, #0\n"
173 " teq %1, %3\n"
174 " strexeq %0, %4, [%2]\n"
175 : "=&r" (res), "=&r" (oldval)
176 : "r" (ptr), "Ir" (old), "r" (new)
177 : "memory", "cc");
178 } while (res);
179 break;
180 default:
181 __bad_cmpxchg(ptr, size);
182 oldval = 0;
183 }
184
185 return oldval;
186}
187
188static inline unsigned long __cmpxchg_mb(volatile void *ptr, unsigned long old,
189 unsigned long new, int size)
190{
191 unsigned long ret;
192
193 smp_mb();
194 ret = __cmpxchg(ptr, old, new, size);
195 smp_mb();
196
197 return ret;
198}
199
200#define cmpxchg(ptr,o,n) \
201 ((__typeof__(*(ptr)))__cmpxchg_mb((ptr), \
202 (unsigned long)(o), \
203 (unsigned long)(n), \
204 sizeof(*(ptr))))
205
206static inline unsigned long __cmpxchg_local(volatile void *ptr,
207 unsigned long old,
208 unsigned long new, int size)
209{
210 unsigned long ret;
211
212 switch (size) {
213#ifdef CONFIG_CPU_V6 /* min ARCH == ARMv6 */
214 case 1:
215 case 2:
216 ret = __cmpxchg_local_generic(ptr, old, new, size);
217 break;
218#endif
219 default:
220 ret = __cmpxchg(ptr, old, new, size);
221 }
222
223 return ret;
224}
225
226#define cmpxchg_local(ptr,o,n) \
227 ((__typeof__(*(ptr)))__cmpxchg_local((ptr), \
228 (unsigned long)(o), \
229 (unsigned long)(n), \
230 sizeof(*(ptr))))
231
232#ifndef CONFIG_CPU_V6 /* min ARCH >= ARMv6K */
233
234/*
235 * Note : ARMv7-M (currently unsupported by Linux) does not support
236 * ldrexd/strexd. If ARMv7-M is ever supported by the Linux kernel, it should
237 * not be allowed to use __cmpxchg64.
238 */
239static inline unsigned long long __cmpxchg64(volatile void *ptr,
240 unsigned long long old,
241 unsigned long long new)
242{
243 register unsigned long long oldval asm("r0");
244 register unsigned long long __old asm("r2") = old;
245 register unsigned long long __new asm("r4") = new;
246 unsigned long res;
247
248 do {
249 asm volatile(
250 " @ __cmpxchg8\n"
251 " ldrexd %1, %H1, [%2]\n"
252 " mov %0, #0\n"
253 " teq %1, %3\n"
254 " teqeq %H1, %H3\n"
255 " strexdeq %0, %4, %H4, [%2]\n"
256 : "=&r" (res), "=&r" (oldval)
257 : "r" (ptr), "Ir" (__old), "r" (__new)
258 : "memory", "cc");
259 } while (res);
260
261 return oldval;
262}
263
264static inline unsigned long long __cmpxchg64_mb(volatile void *ptr,
265 unsigned long long old,
266 unsigned long long new)
267{
268 unsigned long long ret;
269
270 smp_mb();
271 ret = __cmpxchg64(ptr, old, new);
272 smp_mb();
273
274 return ret;
275}
276
277#define cmpxchg64(ptr,o,n) \
278 ((__typeof__(*(ptr)))__cmpxchg64_mb((ptr), \
279 (unsigned long long)(o), \
280 (unsigned long long)(n)))
281
282#define cmpxchg64_local(ptr,o,n) \
283 ((__typeof__(*(ptr)))__cmpxchg64((ptr), \
284 (unsigned long long)(o), \
285 (unsigned long long)(n)))
286
287#else /* min ARCH = ARMv6 */
288
289#define cmpxchg64_local(ptr, o, n) __cmpxchg64_local_generic((ptr), (o), (n))
290
291#endif
292
293#endif /* __LINUX_ARM_ARCH__ >= 6 */
294
295#endif /* __ASM_ARM_CMPXCHG_H */
diff --git a/arch/arm/include/asm/compiler.h b/arch/arm/include/asm/compiler.h
new file mode 100644
index 00000000000..8155db2f7fa
--- /dev/null
+++ b/arch/arm/include/asm/compiler.h
@@ -0,0 +1,15 @@
1#ifndef __ASM_ARM_COMPILER_H
2#define __ASM_ARM_COMPILER_H
3
4/*
5 * This is used to ensure the compiler did actually allocate the register we
6 * asked it for some inline assembly sequences. Apparently we can't trust
7 * the compiler from one version to another so a bit of paranoia won't hurt.
8 * This string is meant to be concatenated with the inline asm string and
9 * will cause compilation to stop on mismatch.
10 * (for details, see gcc PR 15089)
11 */
12#define __asmeq(x, y) ".ifnc " x "," y " ; .err ; .endif\n\t"
13
14
15#endif /* __ASM_ARM_COMPILER_H */
diff --git a/arch/arm/include/asm/cp15.h b/arch/arm/include/asm/cp15.h
index 3dabd8dd404..5ef4d8015a6 100644
--- a/arch/arm/include/asm/cp15.h
+++ b/arch/arm/include/asm/cp15.h
@@ -1,7 +1,7 @@
1#ifndef __ASM_ARM_CP15_H 1#ifndef __ASM_ARM_CP15_H
2#define __ASM_ARM_CP15_H 2#define __ASM_ARM_CP15_H
3 3
4#include <asm/system.h> 4#include <asm/barrier.h>
5 5
6/* 6/*
7 * CR1 bits (CP#15 CR1) 7 * CR1 bits (CP#15 CR1)
diff --git a/arch/arm/include/asm/div64.h b/arch/arm/include/asm/div64.h
index d3f0a9eee9f..fe92ccf1d0b 100644
--- a/arch/arm/include/asm/div64.h
+++ b/arch/arm/include/asm/div64.h
@@ -1,8 +1,8 @@
1#ifndef __ASM_ARM_DIV64 1#ifndef __ASM_ARM_DIV64
2#define __ASM_ARM_DIV64 2#define __ASM_ARM_DIV64
3 3
4#include <asm/system.h>
5#include <linux/types.h> 4#include <linux/types.h>
5#include <asm/compiler.h>
6 6
7/* 7/*
8 * The semantics of do_div() are: 8 * The semantics of do_div() are:
diff --git a/arch/arm/include/asm/dma.h b/arch/arm/include/asm/dma.h
index 69a5b0b6455..5694a0d6576 100644
--- a/arch/arm/include/asm/dma.h
+++ b/arch/arm/include/asm/dma.h
@@ -19,7 +19,6 @@
19 * It should not be re-used except for that purpose. 19 * It should not be re-used except for that purpose.
20 */ 20 */
21#include <linux/spinlock.h> 21#include <linux/spinlock.h>
22#include <asm/system.h>
23#include <asm/scatterlist.h> 22#include <asm/scatterlist.h>
24 23
25#include <mach/isa-dma.h> 24#include <mach/isa-dma.h>
diff --git a/arch/arm/include/asm/domain.h b/arch/arm/include/asm/domain.h
index b5dc173d336..3d2220498ab 100644
--- a/arch/arm/include/asm/domain.h
+++ b/arch/arm/include/asm/domain.h
@@ -10,6 +10,10 @@
10#ifndef __ASM_PROC_DOMAIN_H 10#ifndef __ASM_PROC_DOMAIN_H
11#define __ASM_PROC_DOMAIN_H 11#define __ASM_PROC_DOMAIN_H
12 12
13#ifndef __ASSEMBLY__
14#include <asm/barrier.h>
15#endif
16
13/* 17/*
14 * Domain numbers 18 * Domain numbers
15 * 19 *
diff --git a/arch/arm/include/asm/exec.h b/arch/arm/include/asm/exec.h
new file mode 100644
index 00000000000..7c4fbef72b3
--- /dev/null
+++ b/arch/arm/include/asm/exec.h
@@ -0,0 +1,6 @@
1#ifndef __ASM_ARM_EXEC_H
2#define __ASM_ARM_EXEC_H
3
4#define arch_align_stack(x) (x)
5
6#endif /* __ASM_ARM_EXEC_H */
diff --git a/arch/arm/include/asm/io.h b/arch/arm/include/asm/io.h
index 9275828feb3..bae7eb6011d 100644
--- a/arch/arm/include/asm/io.h
+++ b/arch/arm/include/asm/io.h
@@ -26,7 +26,6 @@
26#include <linux/types.h> 26#include <linux/types.h>
27#include <asm/byteorder.h> 27#include <asm/byteorder.h>
28#include <asm/memory.h> 28#include <asm/memory.h>
29#include <asm/system.h>
30#include <asm-generic/pci_iomap.h> 29#include <asm-generic/pci_iomap.h>
31 30
32/* 31/*
@@ -99,6 +98,7 @@ static inline void __iomem *__typesafe_io(unsigned long addr)
99 98
100/* IO barriers */ 99/* IO barriers */
101#ifdef CONFIG_ARM_DMA_MEM_BUFFERABLE 100#ifdef CONFIG_ARM_DMA_MEM_BUFFERABLE
101#include <asm/barrier.h>
102#define __iormb() rmb() 102#define __iormb() rmb()
103#define __iowmb() wmb() 103#define __iowmb() wmb()
104#else 104#else
diff --git a/arch/arm/include/asm/mmu.h b/arch/arm/include/asm/mmu.h
index 14965658a92..b8e580a297e 100644
--- a/arch/arm/include/asm/mmu.h
+++ b/arch/arm/include/asm/mmu.h
@@ -34,4 +34,11 @@ typedef struct {
34 34
35#endif 35#endif
36 36
37/*
38 * switch_mm() may do a full cache flush over the context switch,
39 * so enable interrupts over the context switch to avoid high
40 * latency.
41 */
42#define __ARCH_WANT_INTERRUPTS_ON_CTXSW
43
37#endif 44#endif
diff --git a/arch/arm/include/asm/processor.h b/arch/arm/include/asm/processor.h
index cb8d638924f..f4d7f56ee51 100644
--- a/arch/arm/include/asm/processor.h
+++ b/arch/arm/include/asm/processor.h
@@ -22,7 +22,6 @@
22#include <asm/hw_breakpoint.h> 22#include <asm/hw_breakpoint.h>
23#include <asm/ptrace.h> 23#include <asm/ptrace.h>
24#include <asm/types.h> 24#include <asm/types.h>
25#include <asm/system.h>
26 25
27#ifdef __KERNEL__ 26#ifdef __KERNEL__
28#define STACK_TOP ((current->personality & ADDR_LIMIT_32BIT) ? \ 27#define STACK_TOP ((current->personality & ADDR_LIMIT_32BIT) ? \
@@ -90,6 +89,8 @@ unsigned long get_wchan(struct task_struct *p);
90#define cpu_relax() barrier() 89#define cpu_relax() barrier()
91#endif 90#endif
92 91
92void cpu_idle_wait(void);
93
93/* 94/*
94 * Create a new kernel thread 95 * Create a new kernel thread
95 */ 96 */
diff --git a/arch/arm/include/asm/switch_to.h b/arch/arm/include/asm/switch_to.h
new file mode 100644
index 00000000000..fa09e6b49bf
--- /dev/null
+++ b/arch/arm/include/asm/switch_to.h
@@ -0,0 +1,18 @@
1#ifndef __ASM_ARM_SWITCH_TO_H
2#define __ASM_ARM_SWITCH_TO_H
3
4#include <linux/thread_info.h>
5
6/*
7 * switch_to(prev, next) should switch from task `prev' to `next'
8 * `prev' will never be the same as `next'. schedule() itself
9 * contains the memory barrier to tell GCC not to cache `current'.
10 */
11extern struct task_struct *__switch_to(struct task_struct *, struct thread_info *, struct thread_info *);
12
13#define switch_to(prev,next,last) \
14do { \
15 last = __switch_to(prev,task_thread_info(prev), task_thread_info(next)); \
16} while (0)
17
18#endif /* __ASM_ARM_SWITCH_TO_H */
diff --git a/arch/arm/include/asm/system.h b/arch/arm/include/asm/system.h
index 774c41e8add..74542c52f9b 100644
--- a/arch/arm/include/asm/system.h
+++ b/arch/arm/include/asm/system.h
@@ -1,466 +1,8 @@
1#ifndef __ASM_ARM_SYSTEM_H 1/* FILE TO BE DELETED. DO NOT ADD STUFF HERE! */
2#define __ASM_ARM_SYSTEM_H 2#include <asm/barrier.h>
3 3#include <asm/compiler.h>
4#ifdef __KERNEL__ 4#include <asm/cmpxchg.h>
5 5#include <asm/exec.h>
6#define CPU_ARCH_UNKNOWN 0 6#include <asm/switch_to.h>
7#define CPU_ARCH_ARMv3 1 7#include <asm/system_info.h>
8#define CPU_ARCH_ARMv4 2 8#include <asm/system_misc.h>
9#define CPU_ARCH_ARMv4T 3
10#define CPU_ARCH_ARMv5 4
11#define CPU_ARCH_ARMv5T 5
12#define CPU_ARCH_ARMv5TE 6
13#define CPU_ARCH_ARMv5TEJ 7
14#define CPU_ARCH_ARMv6 8
15#define CPU_ARCH_ARMv7 9
16
17/*
18 * This is used to ensure the compiler did actually allocate the register we
19 * asked it for some inline assembly sequences. Apparently we can't trust
20 * the compiler from one version to another so a bit of paranoia won't hurt.
21 * This string is meant to be concatenated with the inline asm string and
22 * will cause compilation to stop on mismatch.
23 * (for details, see gcc PR 15089)
24 */
25#define __asmeq(x, y) ".ifnc " x "," y " ; .err ; .endif\n\t"
26
27#ifndef __ASSEMBLY__
28
29#include <linux/compiler.h>
30#include <linux/linkage.h>
31#include <linux/irqflags.h>
32
33#include <asm/outercache.h>
34
35struct thread_info;
36struct task_struct;
37
38/* information about the system we're running on */
39extern unsigned int system_rev;
40extern unsigned int system_serial_low;
41extern unsigned int system_serial_high;
42extern unsigned int mem_fclk_21285;
43
44struct pt_regs;
45
46void die(const char *msg, struct pt_regs *regs, int err);
47
48struct siginfo;
49void arm_notify_die(const char *str, struct pt_regs *regs, struct siginfo *info,
50 unsigned long err, unsigned long trap);
51
52#ifdef CONFIG_ARM_LPAE
53#define FAULT_CODE_ALIGNMENT 33
54#define FAULT_CODE_DEBUG 34
55#else
56#define FAULT_CODE_ALIGNMENT 1
57#define FAULT_CODE_DEBUG 2
58#endif
59
60void hook_fault_code(int nr, int (*fn)(unsigned long, unsigned int,
61 struct pt_regs *),
62 int sig, int code, const char *name);
63
64void hook_ifault_code(int nr, int (*fn)(unsigned long, unsigned int,
65 struct pt_regs *),
66 int sig, int code, const char *name);
67
68#define xchg(ptr,x) \
69 ((__typeof__(*(ptr)))__xchg((unsigned long)(x),(ptr),sizeof(*(ptr))))
70
71extern asmlinkage void c_backtrace(unsigned long fp, int pmode);
72
73struct mm_struct;
74extern void show_pte(struct mm_struct *mm, unsigned long addr);
75extern void __show_regs(struct pt_regs *);
76
77extern int __pure cpu_architecture(void);
78extern void cpu_init(void);
79
80void soft_restart(unsigned long);
81extern void (*arm_pm_restart)(char str, const char *cmd);
82
83#define UDBG_UNDEFINED (1 << 0)
84#define UDBG_SYSCALL (1 << 1)
85#define UDBG_BADABORT (1 << 2)
86#define UDBG_SEGV (1 << 3)
87#define UDBG_BUS (1 << 4)
88
89extern unsigned int user_debug;
90
91#if __LINUX_ARM_ARCH__ >= 7 || \
92 (__LINUX_ARM_ARCH__ == 6 && defined(CONFIG_CPU_32v6K))
93#define sev() __asm__ __volatile__ ("sev" : : : "memory")
94#define wfe() __asm__ __volatile__ ("wfe" : : : "memory")
95#define wfi() __asm__ __volatile__ ("wfi" : : : "memory")
96#endif
97
98#if __LINUX_ARM_ARCH__ >= 7
99#define isb() __asm__ __volatile__ ("isb" : : : "memory")
100#define dsb() __asm__ __volatile__ ("dsb" : : : "memory")
101#define dmb() __asm__ __volatile__ ("dmb" : : : "memory")
102#elif defined(CONFIG_CPU_XSC3) || __LINUX_ARM_ARCH__ == 6
103#define isb() __asm__ __volatile__ ("mcr p15, 0, %0, c7, c5, 4" \
104 : : "r" (0) : "memory")
105#define dsb() __asm__ __volatile__ ("mcr p15, 0, %0, c7, c10, 4" \
106 : : "r" (0) : "memory")
107#define dmb() __asm__ __volatile__ ("mcr p15, 0, %0, c7, c10, 5" \
108 : : "r" (0) : "memory")
109#elif defined(CONFIG_CPU_FA526)
110#define isb() __asm__ __volatile__ ("mcr p15, 0, %0, c7, c5, 4" \
111 : : "r" (0) : "memory")
112#define dsb() __asm__ __volatile__ ("mcr p15, 0, %0, c7, c10, 4" \
113 : : "r" (0) : "memory")
114#define dmb() __asm__ __volatile__ ("" : : : "memory")
115#else
116#define isb() __asm__ __volatile__ ("" : : : "memory")
117#define dsb() __asm__ __volatile__ ("mcr p15, 0, %0, c7, c10, 4" \
118 : : "r" (0) : "memory")
119#define dmb() __asm__ __volatile__ ("" : : : "memory")
120#endif
121
122#ifdef CONFIG_ARCH_HAS_BARRIERS
123#include <mach/barriers.h>
124#elif defined(CONFIG_ARM_DMA_MEM_BUFFERABLE) || defined(CONFIG_SMP)
125#define mb() do { dsb(); outer_sync(); } while (0)
126#define rmb() dsb()
127#define wmb() mb()
128#else
129#include <asm/memory.h>
130#define mb() do { if (arch_is_coherent()) dmb(); else barrier(); } while (0)
131#define rmb() do { if (arch_is_coherent()) dmb(); else barrier(); } while (0)
132#define wmb() do { if (arch_is_coherent()) dmb(); else barrier(); } while (0)
133#endif
134
135#ifndef CONFIG_SMP
136#define smp_mb() barrier()
137#define smp_rmb() barrier()
138#define smp_wmb() barrier()
139#else
140#define smp_mb() dmb()
141#define smp_rmb() dmb()
142#define smp_wmb() dmb()
143#endif
144
145#define read_barrier_depends() do { } while(0)
146#define smp_read_barrier_depends() do { } while(0)
147
148#define set_mb(var, value) do { var = value; smp_mb(); } while (0)
149#define nop() __asm__ __volatile__("mov\tr0,r0\t@ nop\n\t");
150
151/*
152 * switch_mm() may do a full cache flush over the context switch,
153 * so enable interrupts over the context switch to avoid high
154 * latency.
155 */
156#define __ARCH_WANT_INTERRUPTS_ON_CTXSW
157
158/*
159 * switch_to(prev, next) should switch from task `prev' to `next'
160 * `prev' will never be the same as `next'. schedule() itself
161 * contains the memory barrier to tell GCC not to cache `current'.
162 */
163extern struct task_struct *__switch_to(struct task_struct *, struct thread_info *, struct thread_info *);
164
165#define switch_to(prev,next,last) \
166do { \
167 last = __switch_to(prev,task_thread_info(prev), task_thread_info(next)); \
168} while (0)
169
170#if defined(CONFIG_CPU_SA1100) || defined(CONFIG_CPU_SA110)
171/*
172 * On the StrongARM, "swp" is terminally broken since it bypasses the
173 * cache totally. This means that the cache becomes inconsistent, and,
174 * since we use normal loads/stores as well, this is really bad.
175 * Typically, this causes oopsen in filp_close, but could have other,
176 * more disastrous effects. There are two work-arounds:
177 * 1. Disable interrupts and emulate the atomic swap
178 * 2. Clean the cache, perform atomic swap, flush the cache
179 *
180 * We choose (1) since its the "easiest" to achieve here and is not
181 * dependent on the processor type.
182 *
183 * NOTE that this solution won't work on an SMP system, so explcitly
184 * forbid it here.
185 */
186#define swp_is_buggy
187#endif
188
189static inline unsigned long __xchg(unsigned long x, volatile void *ptr, int size)
190{
191 extern void __bad_xchg(volatile void *, int);
192 unsigned long ret;
193#ifdef swp_is_buggy
194 unsigned long flags;
195#endif
196#if __LINUX_ARM_ARCH__ >= 6
197 unsigned int tmp;
198#endif
199
200 smp_mb();
201
202 switch (size) {
203#if __LINUX_ARM_ARCH__ >= 6
204 case 1:
205 asm volatile("@ __xchg1\n"
206 "1: ldrexb %0, [%3]\n"
207 " strexb %1, %2, [%3]\n"
208 " teq %1, #0\n"
209 " bne 1b"
210 : "=&r" (ret), "=&r" (tmp)
211 : "r" (x), "r" (ptr)
212 : "memory", "cc");
213 break;
214 case 4:
215 asm volatile("@ __xchg4\n"
216 "1: ldrex %0, [%3]\n"
217 " strex %1, %2, [%3]\n"
218 " teq %1, #0\n"
219 " bne 1b"
220 : "=&r" (ret), "=&r" (tmp)
221 : "r" (x), "r" (ptr)
222 : "memory", "cc");
223 break;
224#elif defined(swp_is_buggy)
225#ifdef CONFIG_SMP
226#error SMP is not supported on this platform
227#endif
228 case 1:
229 raw_local_irq_save(flags);
230 ret = *(volatile unsigned char *)ptr;
231 *(volatile unsigned char *)ptr = x;
232 raw_local_irq_restore(flags);
233 break;
234
235 case 4:
236 raw_local_irq_save(flags);
237 ret = *(volatile unsigned long *)ptr;
238 *(volatile unsigned long *)ptr = x;
239 raw_local_irq_restore(flags);
240 break;
241#else
242 case 1:
243 asm volatile("@ __xchg1\n"
244 " swpb %0, %1, [%2]"
245 : "=&r" (ret)
246 : "r" (x), "r" (ptr)
247 : "memory", "cc");
248 break;
249 case 4:
250 asm volatile("@ __xchg4\n"
251 " swp %0, %1, [%2]"
252 : "=&r" (ret)
253 : "r" (x), "r" (ptr)
254 : "memory", "cc");
255 break;
256#endif
257 default:
258 __bad_xchg(ptr, size), ret = 0;
259 break;
260 }
261 smp_mb();
262
263 return ret;
264}
265
266extern void disable_hlt(void);
267extern void enable_hlt(void);
268
269void cpu_idle_wait(void);
270
271#include <asm-generic/cmpxchg-local.h>
272
273#if __LINUX_ARM_ARCH__ < 6
274/* min ARCH < ARMv6 */
275
276#ifdef CONFIG_SMP
277#error "SMP is not supported on this platform"
278#endif
279
280/*
281 * cmpxchg_local and cmpxchg64_local are atomic wrt current CPU. Always make
282 * them available.
283 */
284#define cmpxchg_local(ptr, o, n) \
285 ((__typeof__(*(ptr)))__cmpxchg_local_generic((ptr), (unsigned long)(o),\
286 (unsigned long)(n), sizeof(*(ptr))))
287#define cmpxchg64_local(ptr, o, n) __cmpxchg64_local_generic((ptr), (o), (n))
288
289#ifndef CONFIG_SMP
290#include <asm-generic/cmpxchg.h>
291#endif
292
293#else /* min ARCH >= ARMv6 */
294
295extern void __bad_cmpxchg(volatile void *ptr, int size);
296
297/*
298 * cmpxchg only support 32-bits operands on ARMv6.
299 */
300
301static inline unsigned long __cmpxchg(volatile void *ptr, unsigned long old,
302 unsigned long new, int size)
303{
304 unsigned long oldval, res;
305
306 switch (size) {
307#ifndef CONFIG_CPU_V6 /* min ARCH >= ARMv6K */
308 case 1:
309 do {
310 asm volatile("@ __cmpxchg1\n"
311 " ldrexb %1, [%2]\n"
312 " mov %0, #0\n"
313 " teq %1, %3\n"
314 " strexbeq %0, %4, [%2]\n"
315 : "=&r" (res), "=&r" (oldval)
316 : "r" (ptr), "Ir" (old), "r" (new)
317 : "memory", "cc");
318 } while (res);
319 break;
320 case 2:
321 do {
322 asm volatile("@ __cmpxchg1\n"
323 " ldrexh %1, [%2]\n"
324 " mov %0, #0\n"
325 " teq %1, %3\n"
326 " strexheq %0, %4, [%2]\n"
327 : "=&r" (res), "=&r" (oldval)
328 : "r" (ptr), "Ir" (old), "r" (new)
329 : "memory", "cc");
330 } while (res);
331 break;
332#endif
333 case 4:
334 do {
335 asm volatile("@ __cmpxchg4\n"
336 " ldrex %1, [%2]\n"
337 " mov %0, #0\n"
338 " teq %1, %3\n"
339 " strexeq %0, %4, [%2]\n"
340 : "=&r" (res), "=&r" (oldval)
341 : "r" (ptr), "Ir" (old), "r" (new)
342 : "memory", "cc");
343 } while (res);
344 break;
345 default:
346 __bad_cmpxchg(ptr, size);
347 oldval = 0;
348 }
349
350 return oldval;
351}
352
353static inline unsigned long __cmpxchg_mb(volatile void *ptr, unsigned long old,
354 unsigned long new, int size)
355{
356 unsigned long ret;
357
358 smp_mb();
359 ret = __cmpxchg(ptr, old, new, size);
360 smp_mb();
361
362 return ret;
363}
364
365#define cmpxchg(ptr,o,n) \
366 ((__typeof__(*(ptr)))__cmpxchg_mb((ptr), \
367 (unsigned long)(o), \
368 (unsigned long)(n), \
369 sizeof(*(ptr))))
370
371static inline unsigned long __cmpxchg_local(volatile void *ptr,
372 unsigned long old,
373 unsigned long new, int size)
374{
375 unsigned long ret;
376
377 switch (size) {
378#ifdef CONFIG_CPU_V6 /* min ARCH == ARMv6 */
379 case 1:
380 case 2:
381 ret = __cmpxchg_local_generic(ptr, old, new, size);
382 break;
383#endif
384 default:
385 ret = __cmpxchg(ptr, old, new, size);
386 }
387
388 return ret;
389}
390
391#define cmpxchg_local(ptr,o,n) \
392 ((__typeof__(*(ptr)))__cmpxchg_local((ptr), \
393 (unsigned long)(o), \
394 (unsigned long)(n), \
395 sizeof(*(ptr))))
396
397#ifndef CONFIG_CPU_V6 /* min ARCH >= ARMv6K */
398
399/*
400 * Note : ARMv7-M (currently unsupported by Linux) does not support
401 * ldrexd/strexd. If ARMv7-M is ever supported by the Linux kernel, it should
402 * not be allowed to use __cmpxchg64.
403 */
404static inline unsigned long long __cmpxchg64(volatile void *ptr,
405 unsigned long long old,
406 unsigned long long new)
407{
408 register unsigned long long oldval asm("r0");
409 register unsigned long long __old asm("r2") = old;
410 register unsigned long long __new asm("r4") = new;
411 unsigned long res;
412
413 do {
414 asm volatile(
415 " @ __cmpxchg8\n"
416 " ldrexd %1, %H1, [%2]\n"
417 " mov %0, #0\n"
418 " teq %1, %3\n"
419 " teqeq %H1, %H3\n"
420 " strexdeq %0, %4, %H4, [%2]\n"
421 : "=&r" (res), "=&r" (oldval)
422 : "r" (ptr), "Ir" (__old), "r" (__new)
423 : "memory", "cc");
424 } while (res);
425
426 return oldval;
427}
428
429static inline unsigned long long __cmpxchg64_mb(volatile void *ptr,
430 unsigned long long old,
431 unsigned long long new)
432{
433 unsigned long long ret;
434
435 smp_mb();
436 ret = __cmpxchg64(ptr, old, new);
437 smp_mb();
438
439 return ret;
440}
441
442#define cmpxchg64(ptr,o,n) \
443 ((__typeof__(*(ptr)))__cmpxchg64_mb((ptr), \
444 (unsigned long long)(o), \
445 (unsigned long long)(n)))
446
447#define cmpxchg64_local(ptr,o,n) \
448 ((__typeof__(*(ptr)))__cmpxchg64((ptr), \
449 (unsigned long long)(o), \
450 (unsigned long long)(n)))
451
452#else /* min ARCH = ARMv6 */
453
454#define cmpxchg64_local(ptr, o, n) __cmpxchg64_local_generic((ptr), (o), (n))
455
456#endif
457
458#endif /* __LINUX_ARM_ARCH__ >= 6 */
459
460#endif /* __ASSEMBLY__ */
461
462#define arch_align_stack(x) (x)
463
464#endif /* __KERNEL__ */
465
466#endif
diff --git a/arch/arm/include/asm/system_info.h b/arch/arm/include/asm/system_info.h
new file mode 100644
index 00000000000..dfd386d0c02
--- /dev/null
+++ b/arch/arm/include/asm/system_info.h
@@ -0,0 +1,27 @@
1#ifndef __ASM_ARM_SYSTEM_INFO_H
2#define __ASM_ARM_SYSTEM_INFO_H
3
4#define CPU_ARCH_UNKNOWN 0
5#define CPU_ARCH_ARMv3 1
6#define CPU_ARCH_ARMv4 2
7#define CPU_ARCH_ARMv4T 3
8#define CPU_ARCH_ARMv5 4
9#define CPU_ARCH_ARMv5T 5
10#define CPU_ARCH_ARMv5TE 6
11#define CPU_ARCH_ARMv5TEJ 7
12#define CPU_ARCH_ARMv6 8
13#define CPU_ARCH_ARMv7 9
14
15#ifndef __ASSEMBLY__
16
17/* information about the system we're running on */
18extern unsigned int system_rev;
19extern unsigned int system_serial_low;
20extern unsigned int system_serial_high;
21extern unsigned int mem_fclk_21285;
22
23extern int __pure cpu_architecture(void);
24
25#endif /* !__ASSEMBLY__ */
26
27#endif /* __ASM_ARM_SYSTEM_INFO_H */
diff --git a/arch/arm/include/asm/system_misc.h b/arch/arm/include/asm/system_misc.h
new file mode 100644
index 00000000000..9e65b23be14
--- /dev/null
+++ b/arch/arm/include/asm/system_misc.h
@@ -0,0 +1,28 @@
1#ifndef __ASM_ARM_SYSTEM_MISC_H
2#define __ASM_ARM_SYSTEM_MISC_H
3
4#ifndef __ASSEMBLY__
5
6#include <linux/compiler.h>
7#include <linux/linkage.h>
8#include <linux/irqflags.h>
9
10extern void cpu_init(void);
11
12void soft_restart(unsigned long);
13extern void (*arm_pm_restart)(char str, const char *cmd);
14
15#define UDBG_UNDEFINED (1 << 0)
16#define UDBG_SYSCALL (1 << 1)
17#define UDBG_BADABORT (1 << 2)
18#define UDBG_SEGV (1 << 3)
19#define UDBG_BUS (1 << 4)
20
21extern unsigned int user_debug;
22
23extern void disable_hlt(void);
24extern void enable_hlt(void);
25
26#endif /* !__ASSEMBLY__ */
27
28#endif /* __ASM_ARM_SYSTEM_MISC_H */
diff --git a/arch/arm/include/asm/uaccess.h b/arch/arm/include/asm/uaccess.h
index 2958976d867..71f6536d17a 100644
--- a/arch/arm/include/asm/uaccess.h
+++ b/arch/arm/include/asm/uaccess.h
@@ -16,8 +16,8 @@
16#include <asm/errno.h> 16#include <asm/errno.h>
17#include <asm/memory.h> 17#include <asm/memory.h>
18#include <asm/domain.h> 18#include <asm/domain.h>
19#include <asm/system.h>
20#include <asm/unified.h> 19#include <asm/unified.h>
20#include <asm/compiler.h>
21 21
22#define VERIFY_READ 0 22#define VERIFY_READ 0
23#define VERIFY_WRITE 1 23#define VERIFY_WRITE 1