Linux 2.6.39-rc2
[pohmelfs.git] / arch / blackfin / kernel / fixed_code.S
blob0565917f23ba7a699709db2f9b7518fce24cc0cb
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  * Copyright 2007-2008 Analog Devices Inc.
11  *
12  * Licensed under the GPL-2 or later.
13  */
15 #include <linux/linkage.h>
16 #include <linux/init.h>
17 #include <linux/unistd.h>
18 #include <asm/entry.h>
20 __INIT
22 ENTRY(_fixed_code_start)
24 .align 16
25 ENTRY(_sigreturn_stub)
26         P0 = __NR_rt_sigreturn;
27         EXCPT 0;
28         /* Speculative execution paranoia.  */
29 0:      JUMP.S 0b;
30 ENDPROC (_sigreturn_stub)
32 .align 16
33         /*
34          * Atomic swap, 8 bit.
35          * Inputs:      P0: memory address to use
36          *              R1: value to store
37          * Output:      R0: old contents of the memory address, zero extended.
38          */
39 ENTRY(_atomic_xchg32)
40         R0 = [P0];
41         [P0] = R1;
42         rts;
43 ENDPROC (_atomic_xchg32)
45 .align 16
46         /*
47          * Compare and swap, 32 bit.
48          * Inputs:      P0: memory address to use
49          *              R1: compare value
50          *              R2: new value to store
51          * The new value is stored if the contents of the memory
52          * address is equal to the compare value.
53          * Output:      R0: old contents of the memory address.
54          */
55 ENTRY(_atomic_cas32)
56         R0 = [P0];
57         CC = R0 == R1;
58         IF !CC JUMP 1f;
59         [P0] = R2;
61         rts;
62 ENDPROC (_atomic_cas32)
64 .align 16
65         /*
66          * Atomic add, 32 bit.
67          * Inputs:      P0: memory address to use
68          *              R0: value to add
69          * Outputs:     R0: new contents of the memory address.
70          *              R1: previous contents of the memory address.
71          */
72 ENTRY(_atomic_add32)
73         R1 = [P0];
74         R0 = R1 + R0;
75         [P0] = R0;
76         rts;
77 ENDPROC (_atomic_add32)
79 .align 16
80         /*
81          * Atomic sub, 32 bit.
82          * Inputs:      P0: memory address to use
83          *              R0: value to subtract
84          * Outputs:     R0: new contents of the memory address.
85          *              R1: previous contents of the memory address.
86          */
87 ENTRY(_atomic_sub32)
88         R1 = [P0];
89         R0 = R1 - R0;
90         [P0] = R0;
91         rts;
92 ENDPROC (_atomic_sub32)
94 .align 16
95         /*
96          * Atomic ior, 32 bit.
97          * Inputs:      P0: memory address to use
98          *              R0: value to ior
99          * Outputs:     R0: new contents of the memory address.
100          *              R1: previous contents of the memory address.
101          */
102 ENTRY(_atomic_ior32)
103         R1 = [P0];
104         R0 = R1 | R0;
105         [P0] = R0;
106         rts;
107 ENDPROC (_atomic_ior32)
109 .align 16
110         /*
111          * Atomic and, 32 bit.
112          * Inputs:      P0: memory address to use
113          *              R0: value to and
114          * Outputs:     R0: new contents of the memory address.
115          *              R1: previous contents of the memory address.
116          */
117 ENTRY(_atomic_and32)
118         R1 = [P0];
119         R0 = R1 & R0;
120         [P0] = R0;
121         rts;
122 ENDPROC (_atomic_and32)
124 .align 16
125         /*
126          * Atomic xor, 32 bit.
127          * Inputs:      P0: memory address to use
128          *              R0: value to xor
129          * Outputs:     R0: new contents of the memory address.
130          *              R1: previous contents of the memory address.
131          */
132 ENTRY(_atomic_xor32)
133         R1 = [P0];
134         R0 = R1 ^ R0;
135         [P0] = R0;
136         rts;
137 ENDPROC (_atomic_xor32)
139 .align 16
140         /*
141          * safe_user_instruction
142          * Four NOPS are enough to allow the pipeline to speculativily load
143          * execute anything it wants. After that, things have gone bad, and
144          * we are stuck - so panic. Since we might be in user space, we can't
145          * call panic, so just cause a unhandled exception, this should cause
146          * a dump of the trace buffer so we can tell were we are, and a reboot
147          */
148 ENTRY(_safe_user_instruction)
149         NOP; NOP; NOP; NOP;
150         EXCPT 0x4;
151 ENDPROC(_safe_user_instruction)
153 ENTRY(_fixed_code_end)
155 __FINIT