Merge branch 'master' of git://git.kernel.org/pub/scm/linux/kernel/git/kaber/nf-2.6
[sfrench/cifs-2.6.git] / arch / blackfin / kernel / fixed_code.S
1 /*
2  * This file contains sequences of code that will be copied to a
3  * fixed location, defined in <asm/fixed_code.h>.  The interrupt
4  * handlers ensure that these sequences appear to be atomic when
5  * executed from userspace.
6  * These are aligned to 16 bytes, so that we have some space to replace
7  * these sequences with something else (e.g. kernel traps if we ever do
8  * BF561 SMP).
9  */
10 #include <linux/linkage.h>
11 #include <linux/init.h>
12 #include <linux/unistd.h>
13 #include <asm/entry.h>
14
15 __INIT
16
17 ENTRY(_fixed_code_start)
18
19 .align 16
20 ENTRY(_sigreturn_stub)
21         P0 = __NR_rt_sigreturn;
22         EXCPT 0;
23         /* Speculative execution paranoia.  */
24 0:      JUMP.S 0b;
25 ENDPROC (_sigreturn_stub)
26
27 .align 16
28         /*
29          * Atomic swap, 8 bit.
30          * Inputs:      P0: memory address to use
31          *              R1: value to store
32          * Output:      R0: old contents of the memory address, zero extended.
33          */
34 ENTRY(_atomic_xchg32)
35         R0 = [P0];
36         [P0] = R1;
37         rts;
38 ENDPROC (_atomic_xchg32)
39
40 .align 16
41         /*
42          * Compare and swap, 32 bit.
43          * Inputs:      P0: memory address to use
44          *              R1: compare value
45          *              R2: new value to store
46          * The new value is stored if the contents of the memory
47          * address is equal to the compare value.
48          * Output:      R0: old contents of the memory address.
49          */
50 ENTRY(_atomic_cas32)
51         R0 = [P0];
52         CC = R0 == R1;
53         IF !CC JUMP 1f;
54         [P0] = R2;
55 1:
56         rts;
57 ENDPROC (_atomic_cas32)
58
59 .align 16
60         /*
61          * Atomic add, 32 bit.
62          * Inputs:      P0: memory address to use
63          *              R0: value to add
64          * Outputs:     R0: new contents of the memory address.
65          *              R1: previous contents of the memory address.
66          */
67 ENTRY(_atomic_add32)
68         R1 = [P0];
69         R0 = R1 + R0;
70         [P0] = R0;
71         rts;
72 ENDPROC (_atomic_add32)
73
74 .align 16
75         /*
76          * Atomic sub, 32 bit.
77          * Inputs:      P0: memory address to use
78          *              R0: value to subtract
79          * Outputs:     R0: new contents of the memory address.
80          *              R1: previous contents of the memory address.
81          */
82 ENTRY(_atomic_sub32)
83         R1 = [P0];
84         R0 = R1 - R0;
85         [P0] = R0;
86         rts;
87 ENDPROC (_atomic_sub32)
88
89 .align 16
90         /*
91          * Atomic ior, 32 bit.
92          * Inputs:      P0: memory address to use
93          *              R0: value to ior
94          * Outputs:     R0: new contents of the memory address.
95          *              R1: previous contents of the memory address.
96          */
97 ENTRY(_atomic_ior32)
98         R1 = [P0];
99         R0 = R1 | R0;
100         [P0] = R0;
101         rts;
102 ENDPROC (_atomic_ior32)
103
104 .align 16
105         /*
106          * Atomic and, 32 bit.
107          * Inputs:      P0: memory address to use
108          *              R0: value to and
109          * Outputs:     R0: new contents of the memory address.
110          *              R1: previous contents of the memory address.
111          */
112 ENTRY(_atomic_and32)
113         R1 = [P0];
114         R0 = R1 & R0;
115         [P0] = R0;
116         rts;
117 ENDPROC (_atomic_and32)
118
119 .align 16
120         /*
121          * Atomic xor, 32 bit.
122          * Inputs:      P0: memory address to use
123          *              R0: value to xor
124          * Outputs:     R0: new contents of the memory address.
125          *              R1: previous contents of the memory address.
126          */
127 ENTRY(_atomic_xor32)
128         R1 = [P0];
129         R0 = R1 ^ R0;
130         [P0] = R0;
131         rts;
132 ENDPROC (_atomic_xor32)
133
134 .align 16
135         /*
136          * safe_user_instruction
137          * Four NOPS are enough to allow the pipeline to speculativily load
138          * execute anything it wants. After that, things have gone bad, and
139          * we are stuck - so panic. Since we might be in user space, we can't
140          * call panic, so just cause a unhandled exception, this should cause
141          * a dump of the trace buffer so we can tell were we are, and a reboot
142          */
143 ENTRY(_safe_user_instruction)
144         NOP; NOP; NOP; NOP;
145         EXCPT 0x4;
146 ENDPROC(_safe_user_instruction)
147
148 ENTRY(_fixed_code_end)
149
150 __FINIT