blob: 0d2d9e0968c834e314f53ad53ded7f889172bd74 [file] [log] [blame]
Bernd Schmidt7adfb582007-06-21 11:34:16 +08001/*
2 * This file contains sequences of code that will be copied to a
Mike Frysinger60c05952008-05-07 11:41:26 +08003 * fixed location, defined in <asm/fixed_code.h>. The interrupt
Bernd Schmidt7adfb582007-06-21 11:34:16 +08004 * 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>
Mike Frysingerbda07aa2008-11-18 17:48:22 +080011#include <linux/init.h>
Mike Frysinger1f83b8f2007-07-12 22:58:21 +080012#include <linux/unistd.h>
Bernd Schmidt7adfb582007-06-21 11:34:16 +080013#include <asm/entry.h>
Bernd Schmidt7adfb582007-06-21 11:34:16 +080014
Mike Frysingerbda07aa2008-11-18 17:48:22 +080015__INIT
16
Bernd Schmidt7adfb582007-06-21 11:34:16 +080017ENTRY(_fixed_code_start)
18
19.align 16
20ENTRY(_sigreturn_stub)
21 P0 = __NR_rt_sigreturn;
22 EXCPT 0;
23 /* Speculative execution paranoia. */
240: JUMP.S 0b;
25ENDPROC (_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 */
34ENTRY(_atomic_xchg32)
35 R0 = [P0];
36 [P0] = R1;
37 rts;
38ENDPROC (_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 */
50ENTRY(_atomic_cas32)
51 R0 = [P0];
52 CC = R0 == R1;
53 IF !CC JUMP 1f;
54 [P0] = R2;
551:
56 rts;
57ENDPROC (_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 */
67ENTRY(_atomic_add32)
68 R1 = [P0];
69 R0 = R1 + R0;
70 [P0] = R0;
71 rts;
72ENDPROC (_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 */
82ENTRY(_atomic_sub32)
83 R1 = [P0];
84 R0 = R1 - R0;
85 [P0] = R0;
86 rts;
87ENDPROC (_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 */
97ENTRY(_atomic_ior32)
98 R1 = [P0];
99 R0 = R1 | R0;
100 [P0] = R0;
101 rts;
102ENDPROC (_atomic_ior32)
103
104.align 16
105 /*
Mike Frysinger11b0be72008-03-03 17:44:14 -0700106 * Atomic and, 32 bit.
Bernd Schmidt7adfb582007-06-21 11:34:16 +0800107 * Inputs: P0: memory address to use
Mike Frysinger11b0be72008-03-03 17:44:14 -0700108 * R0: value to and
Bernd Schmidt7adfb582007-06-21 11:34:16 +0800109 * Outputs: R0: new contents of the memory address.
110 * R1: previous contents of the memory address.
111 */
112ENTRY(_atomic_and32)
113 R1 = [P0];
114 R0 = R1 & R0;
115 [P0] = R0;
116 rts;
Mike Frysinger11b0be72008-03-03 17:44:14 -0700117ENDPROC (_atomic_and32)
Bernd Schmidt7adfb582007-06-21 11:34:16 +0800118
119.align 16
120 /*
Mike Frysinger11b0be72008-03-03 17:44:14 -0700121 * Atomic xor, 32 bit.
Bernd Schmidt7adfb582007-06-21 11:34:16 +0800122 * Inputs: P0: memory address to use
Mike Frysinger11b0be72008-03-03 17:44:14 -0700123 * R0: value to xor
Bernd Schmidt7adfb582007-06-21 11:34:16 +0800124 * Outputs: R0: new contents of the memory address.
125 * R1: previous contents of the memory address.
126 */
127ENTRY(_atomic_xor32)
128 R1 = [P0];
129 R0 = R1 ^ R0;
130 [P0] = R0;
131 rts;
Mike Frysinger11b0be72008-03-03 17:44:14 -0700132ENDPROC (_atomic_xor32)
Bernd Schmidt7adfb582007-06-21 11:34:16 +0800133
Robin Getz9f336a52007-10-29 18:23:28 +0800134.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 */
143ENTRY(_safe_user_instruction)
144 NOP; NOP; NOP; NOP;
145 EXCPT 0x4;
146ENDPROC(_safe_user_instruction)
147
Bernd Schmidt7adfb582007-06-21 11:34:16 +0800148ENTRY(_fixed_code_end)
Mike Frysingerbda07aa2008-11-18 17:48:22 +0800149
150__FINIT