blob: 4b03ba025488edd4ec55d0f2cc9c92d3d9c2313b [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 Frysinger1f83b8f2007-07-12 22:58:21 +080011#include <linux/unistd.h>
Bernd Schmidt7adfb582007-06-21 11:34:16 +080012#include <asm/entry.h>
Bernd Schmidt7adfb582007-06-21 11:34:16 +080013
14.text
15ENTRY(_fixed_code_start)
16
17.align 16
18ENTRY(_sigreturn_stub)
19 P0 = __NR_rt_sigreturn;
20 EXCPT 0;
21 /* Speculative execution paranoia. */
220: JUMP.S 0b;
23ENDPROC (_sigreturn_stub)
24
25.align 16
26 /*
27 * Atomic swap, 8 bit.
28 * Inputs: P0: memory address to use
29 * R1: value to store
30 * Output: R0: old contents of the memory address, zero extended.
31 */
32ENTRY(_atomic_xchg32)
33 R0 = [P0];
34 [P0] = R1;
35 rts;
36ENDPROC (_atomic_xchg32)
37
38.align 16
39 /*
40 * Compare and swap, 32 bit.
41 * Inputs: P0: memory address to use
42 * R1: compare value
43 * R2: new value to store
44 * The new value is stored if the contents of the memory
45 * address is equal to the compare value.
46 * Output: R0: old contents of the memory address.
47 */
48ENTRY(_atomic_cas32)
49 R0 = [P0];
50 CC = R0 == R1;
51 IF !CC JUMP 1f;
52 [P0] = R2;
531:
54 rts;
55ENDPROC (_atomic_cas32)
56
57.align 16
58 /*
59 * Atomic add, 32 bit.
60 * Inputs: P0: memory address to use
61 * R0: value to add
62 * Outputs: R0: new contents of the memory address.
63 * R1: previous contents of the memory address.
64 */
65ENTRY(_atomic_add32)
66 R1 = [P0];
67 R0 = R1 + R0;
68 [P0] = R0;
69 rts;
70ENDPROC (_atomic_add32)
71
72.align 16
73 /*
74 * Atomic sub, 32 bit.
75 * Inputs: P0: memory address to use
76 * R0: value to subtract
77 * Outputs: R0: new contents of the memory address.
78 * R1: previous contents of the memory address.
79 */
80ENTRY(_atomic_sub32)
81 R1 = [P0];
82 R0 = R1 - R0;
83 [P0] = R0;
84 rts;
85ENDPROC (_atomic_sub32)
86
87.align 16
88 /*
89 * Atomic ior, 32 bit.
90 * Inputs: P0: memory address to use
91 * R0: value to ior
92 * Outputs: R0: new contents of the memory address.
93 * R1: previous contents of the memory address.
94 */
95ENTRY(_atomic_ior32)
96 R1 = [P0];
97 R0 = R1 | R0;
98 [P0] = R0;
99 rts;
100ENDPROC (_atomic_ior32)
101
102.align 16
103 /*
Mike Frysinger11b0be72008-03-03 17:44:14 -0700104 * Atomic and, 32 bit.
Bernd Schmidt7adfb582007-06-21 11:34:16 +0800105 * Inputs: P0: memory address to use
Mike Frysinger11b0be72008-03-03 17:44:14 -0700106 * R0: value to and
Bernd Schmidt7adfb582007-06-21 11:34:16 +0800107 * Outputs: R0: new contents of the memory address.
108 * R1: previous contents of the memory address.
109 */
110ENTRY(_atomic_and32)
111 R1 = [P0];
112 R0 = R1 & R0;
113 [P0] = R0;
114 rts;
Mike Frysinger11b0be72008-03-03 17:44:14 -0700115ENDPROC (_atomic_and32)
Bernd Schmidt7adfb582007-06-21 11:34:16 +0800116
117.align 16
118 /*
Mike Frysinger11b0be72008-03-03 17:44:14 -0700119 * Atomic xor, 32 bit.
Bernd Schmidt7adfb582007-06-21 11:34:16 +0800120 * Inputs: P0: memory address to use
Mike Frysinger11b0be72008-03-03 17:44:14 -0700121 * R0: value to xor
Bernd Schmidt7adfb582007-06-21 11:34:16 +0800122 * Outputs: R0: new contents of the memory address.
123 * R1: previous contents of the memory address.
124 */
125ENTRY(_atomic_xor32)
126 R1 = [P0];
127 R0 = R1 ^ R0;
128 [P0] = R0;
129 rts;
Mike Frysinger11b0be72008-03-03 17:44:14 -0700130ENDPROC (_atomic_xor32)
Bernd Schmidt7adfb582007-06-21 11:34:16 +0800131
Robin Getz9f336a52007-10-29 18:23:28 +0800132.align 16
133 /*
134 * safe_user_instruction
135 * Four NOPS are enough to allow the pipeline to speculativily load
136 * execute anything it wants. After that, things have gone bad, and
137 * we are stuck - so panic. Since we might be in user space, we can't
138 * call panic, so just cause a unhandled exception, this should cause
139 * a dump of the trace buffer so we can tell were we are, and a reboot
140 */
141ENTRY(_safe_user_instruction)
142 NOP; NOP; NOP; NOP;
143 EXCPT 0x4;
144ENDPROC(_safe_user_instruction)
145
Bernd Schmidt7adfb582007-06-21 11:34:16 +0800146ENTRY(_fixed_code_end)