blob: 0565917f23ba7a699709db2f9b7518fce24cc0cb [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).
Robin Getz96f10502009-09-24 14:11:24 +00009 *
10 * Copyright 2007-2008 Analog Devices Inc.
11 *
12 * Licensed under the GPL-2 or later.
Bernd Schmidt7adfb582007-06-21 11:34:16 +080013 */
Robin Getz96f10502009-09-24 14:11:24 +000014
Bernd Schmidt7adfb582007-06-21 11:34:16 +080015#include <linux/linkage.h>
Mike Frysingerbda07aa2008-11-18 17:48:22 +080016#include <linux/init.h>
Mike Frysinger1f83b8f2007-07-12 22:58:21 +080017#include <linux/unistd.h>
Bernd Schmidt7adfb582007-06-21 11:34:16 +080018#include <asm/entry.h>
Bernd Schmidt7adfb582007-06-21 11:34:16 +080019
Mike Frysingerbda07aa2008-11-18 17:48:22 +080020__INIT
21
Bernd Schmidt7adfb582007-06-21 11:34:16 +080022ENTRY(_fixed_code_start)
23
24.align 16
25ENTRY(_sigreturn_stub)
26 P0 = __NR_rt_sigreturn;
27 EXCPT 0;
28 /* Speculative execution paranoia. */
290: JUMP.S 0b;
30ENDPROC (_sigreturn_stub)
31
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 */
39ENTRY(_atomic_xchg32)
40 R0 = [P0];
41 [P0] = R1;
42 rts;
43ENDPROC (_atomic_xchg32)
44
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 */
55ENTRY(_atomic_cas32)
56 R0 = [P0];
57 CC = R0 == R1;
58 IF !CC JUMP 1f;
59 [P0] = R2;
601:
61 rts;
62ENDPROC (_atomic_cas32)
63
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 */
72ENTRY(_atomic_add32)
73 R1 = [P0];
74 R0 = R1 + R0;
75 [P0] = R0;
76 rts;
77ENDPROC (_atomic_add32)
78
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 */
87ENTRY(_atomic_sub32)
88 R1 = [P0];
89 R0 = R1 - R0;
90 [P0] = R0;
91 rts;
92ENDPROC (_atomic_sub32)
93
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 */
102ENTRY(_atomic_ior32)
103 R1 = [P0];
104 R0 = R1 | R0;
105 [P0] = R0;
106 rts;
107ENDPROC (_atomic_ior32)
108
109.align 16
110 /*
Mike Frysinger11b0be72008-03-03 17:44:14 -0700111 * Atomic and, 32 bit.
Bernd Schmidt7adfb582007-06-21 11:34:16 +0800112 * Inputs: P0: memory address to use
Mike Frysinger11b0be72008-03-03 17:44:14 -0700113 * R0: value to and
Bernd Schmidt7adfb582007-06-21 11:34:16 +0800114 * Outputs: R0: new contents of the memory address.
115 * R1: previous contents of the memory address.
116 */
117ENTRY(_atomic_and32)
118 R1 = [P0];
119 R0 = R1 & R0;
120 [P0] = R0;
121 rts;
Mike Frysinger11b0be72008-03-03 17:44:14 -0700122ENDPROC (_atomic_and32)
Bernd Schmidt7adfb582007-06-21 11:34:16 +0800123
124.align 16
125 /*
Mike Frysinger11b0be72008-03-03 17:44:14 -0700126 * Atomic xor, 32 bit.
Bernd Schmidt7adfb582007-06-21 11:34:16 +0800127 * Inputs: P0: memory address to use
Mike Frysinger11b0be72008-03-03 17:44:14 -0700128 * R0: value to xor
Bernd Schmidt7adfb582007-06-21 11:34:16 +0800129 * Outputs: R0: new contents of the memory address.
130 * R1: previous contents of the memory address.
131 */
132ENTRY(_atomic_xor32)
133 R1 = [P0];
134 R0 = R1 ^ R0;
135 [P0] = R0;
136 rts;
Mike Frysinger11b0be72008-03-03 17:44:14 -0700137ENDPROC (_atomic_xor32)
Bernd Schmidt7adfb582007-06-21 11:34:16 +0800138
Robin Getz9f336a52007-10-29 18:23:28 +0800139.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 */
148ENTRY(_safe_user_instruction)
149 NOP; NOP; NOP; NOP;
150 EXCPT 0x4;
151ENDPROC(_safe_user_instruction)
152
Bernd Schmidt7adfb582007-06-21 11:34:16 +0800153ENTRY(_fixed_code_end)
Mike Frysingerbda07aa2008-11-18 17:48:22 +0800154
155__FINIT