]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - sys/sparc64/include/asmacros.h
MFV r329502: 7614 zfs device evacuation/removal
[FreeBSD/FreeBSD.git] / sys / sparc64 / include / asmacros.h
1 /*-
2  * SPDX-License-Identifier: BSD-2-Clause-FreeBSD
3  *
4  * Copyright (c) 2001 Jake Burkholder.
5  * Copyright (c) 2011 Marius Strobl <marius@FreeBSD.org>
6  * All rights reserved.
7  *
8  * Redistribution and use in source and binary forms, with or without
9  * modification, are permitted provided that the following conditions
10  * are met:
11  * 1. Redistributions of source code must retain the above copyright
12  *    notice, this list of conditions and the following disclaimer.
13  * 2. Redistributions in binary form must reproduce the above copyright
14  *    notice, this list of conditions and the following disclaimer in the
15  *    documentation and/or other materials provided with the distribution.
16  *
17  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
18  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
20  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
21  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
22  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
23  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
24  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
25  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
26  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
27  * SUCH DAMAGE.
28  *
29  * $FreeBSD$
30  */
31
32 #ifndef _MACHINE_ASMACROS_H_
33 #define _MACHINE_ASMACROS_H_
34
35 #ifdef _KERNEL
36
37 /*
38  * Normal and alternate %g6 point to the pcb of the current process.  Normal,
39  * alternate and interrupt %g7 point to per-cpu data.
40  */
41 #define PCB_REG         %g6
42 #define PCPU_REG        %g7
43
44 /*
45  * Alternate %g5 points to a per-cpu panic stack, which is used as a last
46  * resort, and for temporarily saving alternate globals.
47  */
48 #define ASP_REG         %g5
49
50 #ifdef LOCORE
51
52 /*
53  * Atomically decrement an integer in memory.
54  */
55 #define ATOMIC_DEC_INT(r1, r2, r3)                                      \
56         lduw    [r1], r2 ;                                              \
57 9:      sub     r2, 1, r3 ;                                             \
58         casa    [r1] ASI_N, r2, r3 ;                                    \
59         cmp     r2, r3 ;                                                \
60         bne,pn  %icc, 9b ;                                              \
61          mov    r3, r2
62
63 /*
64  * Atomically increment an integer in memory.
65  */
66 #define ATOMIC_INC_INT(r1, r2, r3)                                      \
67         lduw    [r1], r2 ;                                              \
68 9:      add     r2, 1, r3 ;                                             \
69         casa    [r1] ASI_N, r2, r3 ;                                    \
70         cmp     r2, r3 ;                                                \
71         bne,pn  %icc, 9b ;                                              \
72          mov    r3, r2
73
74 /*
75  * Atomically increment a long in memory.
76  */
77 #define ATOMIC_INC_LONG(r1, r2, r3)                                     \
78         ldx     [r1], r2 ;                                              \
79 9:      add     r2, 1, r3 ;                                             \
80         casxa   [r1] ASI_N, r2, r3 ;                                    \
81         cmp     r2, r3 ;                                                \
82         bne,pn  %xcc, 9b ;                                              \
83          mov    r3, r2
84
85 /*
86  * Atomically clear a number of bits of an integer in memory.
87  */
88 #define ATOMIC_CLEAR_INT(r1, r2, r3, bits)                              \
89         lduw    [r1], r2 ;                                              \
90 9:      andn    r2, bits, r3 ;                                          \
91         casa    [r1] ASI_N, r2, r3 ;                                    \
92         cmp     r2, r3 ;                                                \
93         bne,pn  %icc, 9b ;                                              \
94          mov    r3, r2
95
96 /*
97  * Atomically clear a number of bits of a long in memory.
98  */
99 #define ATOMIC_CLEAR_LONG(r1, r2, r3, bits)                             \
100         ldx     [r1], r2 ;                                              \
101 9:      andn    r2, bits, r3 ;                                          \
102         casxa   [r1] ASI_N, r2, r3 ;                                    \
103         cmp     r2, r3 ;                                                \
104         bne,pn  %xcc, 9b ;                                              \
105          mov    r3, r2
106
107 /*
108  * Atomically load an integer from memory.
109  */
110 #define ATOMIC_LOAD_INT(r1, val)                                        \
111         clr     val ;                                                   \
112         casa    [r1] ASI_N, %g0, val
113
114 /*
115  * Atomically load a long from memory.
116  */
117 #define ATOMIC_LOAD_LONG(r1, val)                                       \
118         clr     val ;                                                   \
119         casxa   [r1] ASI_N, %g0, val
120
121 /*
122  * Atomically set a number of bits of an integer in memory.
123  */
124 #define ATOMIC_SET_INT(r1, r2, r3, bits)                                \
125         lduw    [r1], r2 ;                                              \
126 9:      or      r2, bits, r3 ;                                          \
127         casa    [r1] ASI_N, r2, r3 ;                                    \
128         cmp     r2, r3 ;                                                \
129         bne,pn  %icc, 9b ;                                              \
130          mov    r3, r2
131
132 /*
133  * Atomically set a number of bits of a long in memory.
134  */
135 #define ATOMIC_SET_LONG(r1, r2, r3, bits)                               \
136         ldx     [r1], r2 ;                                              \
137 9:      or      r2, bits, r3 ;                                          \
138         casxa   [r1] ASI_N, r2, r3 ;                                    \
139         cmp     r2, r3 ;                                                \
140         bne,pn  %xcc, 9b ;                                              \
141          mov    r3, r2
142
143 /*
144  * Atomically store an integer in memory.
145  */
146 #define ATOMIC_STORE_INT(r1, r2, r3, val)                               \
147         lduw    [r1], r2 ;                                              \
148 9:      mov     val, r3 ;                                               \
149         casa    [r1] ASI_N, r2, r3 ;                                    \
150         cmp     r2, r3 ;                                                \
151         bne,pn  %icc, 9b ;                                              \
152          mov    r3, r2
153
154 /*
155  * Atomically store a long in memory.
156  */
157 #define ATOMIC_STORE_LONG(r1, r2, r3, val)                              \
158         ldx     [r1], r2 ;                                              \
159 9:      mov     val, r3 ;                                               \
160         casxa   [r1] ASI_N, r2, r3 ;                                    \
161         cmp     r2, r3 ;                                                \
162         bne,pn  %xcc, 9b ;                                              \
163          mov    r3, r2
164
165 #define PCPU(member)    PCPU_REG + PC_ ## member
166 #define PCPU_ADDR(member, reg)                                          \
167         add     PCPU_REG, PC_ ## member, reg
168
169 #define DEBUGGER()                                                      \
170         ta      %xcc, 1
171
172 #define PANIC(msg, r1)                                                  \
173         .sect   .rodata ;                                               \
174 9:      .asciz  msg ;                                                   \
175         .previous ;                                                     \
176         SET(9b, r1, %o0) ;                                              \
177         call    panic ;                                                 \
178          nop
179
180 #ifdef INVARIANTS
181 #define KASSERT(r1, msg)                                                \
182         brnz,pt r1, 8f ;                                                \
183          nop ;                                                          \
184         PANIC(msg, r1) ;                                                \
185 8:
186 #else
187 #define KASSERT(r1, msg)
188 #endif
189
190 #define PUTS(msg, r1)                                                   \
191         .sect   .rodata ;                                               \
192 9:      .asciz  msg ;                                                   \
193         .previous ;                                                     \
194         SET(9b, r1, %o0) ;                                              \
195         call    printf ;                                                \
196          nop
197
198 #define _ALIGN_DATA     .align 8
199
200 #define DATA(name)                                                      \
201         .data ;                                                         \
202         _ALIGN_DATA ;                                                   \
203         .globl  name ;                                                  \
204         .type   name, @object ;                                         \
205 name:
206
207 #define EMPTY
208
209 /*
210  * Generate atomic compare and swap, load and store instructions for the
211  * corresponding width and ASI (or not).  Note that we want to evaluate the
212  * macro args before concatenating, so that EMPTY really turns into nothing.
213  */
214 #define         _LD(w, a)       ld ## w ## a
215 #define         _ST(w, a)       st ## w ## a
216 #define         _CAS(w, a)      cas ## w ## a
217
218 #define         LD(w, a)        _LD(w, a)
219 #define         ST(w, a)        _ST(w, a)
220 #define         CAS(w, a)       _CAS(w, a)
221
222 #endif /* LOCORE */
223
224 #endif /* _KERNEL */
225
226 #endif /* !_MACHINE_ASMACROS_H_ */