]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - sys/arm64/arm64/support.S
sys/{x86,amd64}: remove one of doubled ;s
[FreeBSD/FreeBSD.git] / sys / arm64 / arm64 / support.S
1 /*-
2  * Copyright (c) 2014 Andrew Turner
3  * Copyright (c) 2014-2015 The FreeBSD Foundation
4  * All rights reserved.
5  *
6  * Portions of this software were developed by Andrew Turner
7  * under sponsorship from the FreeBSD Foundation
8  *
9  * Redistribution and use in source and binary forms, with or without
10  * modification, are permitted provided that the following conditions
11  * are met:
12  * 1. Redistributions of source code must retain the above copyright
13  *    notice, this list of conditions and the following disclaimer.
14  * 2. Redistributions in binary form must reproduce the above copyright
15  *    notice, this list of conditions and the following disclaimer in the
16  *    documentation and/or other materials provided with the distribution.
17  *
18  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
19  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
20  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
21  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
22  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
23  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
24  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
25  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
26  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
27  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
28  * SUCH DAMAGE.
29  *
30  */
31
32 #include <machine/asm.h>
33 __FBSDID("$FreeBSD$");
34
35 #include <machine/setjmp.h>
36 #include <machine/param.h>
37 #include <machine/vmparam.h>
38
39 #include "assym.inc"
40
41 /*
42  * One of the fu* or su* functions failed, return -1.
43  */
44 ENTRY(fsu_fault)
45         SET_FAULT_HANDLER(xzr, x1)      /* Reset the handler function */
46         EXIT_USER_ACCESS_CHECK(w0, x1)
47 fsu_fault_nopcb:
48         mov     x0, #-1
49         ret
50 END(fsu_fault)
51
52 /*
53  * int casueword32(volatile uint32_t *, uint32_t, uint32_t *, uint32_t)
54  */
55 ENTRY(casueword32)
56         ldr     x4, =(VM_MAXUSER_ADDRESS-3)
57         cmp     x0, x4
58         b.cs    fsu_fault_nopcb
59         adr     x6, fsu_fault           /* Load the fault handler */
60         mov     w5, #1
61         SET_FAULT_HANDLER(x6, x4)       /* And set it */
62         ENTER_USER_ACCESS(w6, x4)
63 1:      ldxr    w4, [x0]                /* Load-exclusive the data */
64         cmp     w4, w1                  /* Compare */
65         b.ne    2f                      /* Not equal, exit */
66         stxr    w5, w3, [x0]            /* Store the new data */
67 2:      EXIT_USER_ACCESS(w6)
68         SET_FAULT_HANDLER(xzr, x6)      /* Reset the fault handler */
69         str     w4, [x2]                /* Store the read data */
70         mov     w0, w5                  /* Result same as store status */
71         ret                             /* Return */
72 END(casueword32)
73
74 /*
75  * int casueword(volatile u_long *, u_long, u_long *, u_long)
76  */
77 ENTRY(casueword)
78         ldr     x4, =(VM_MAXUSER_ADDRESS-7)
79         cmp     x0, x4
80         b.cs    fsu_fault_nopcb
81         adr     x6, fsu_fault           /* Load the fault handler */
82         mov     w5, #1
83         SET_FAULT_HANDLER(x6, x4)       /* And set it */
84         ENTER_USER_ACCESS(w6, x4)
85 1:      ldxr    x4, [x0]                /* Load-exclusive the data */
86         cmp     x4, x1                  /* Compare */
87         b.ne    2f                      /* Not equal, exit */
88         stxr    w5, x3, [x0]            /* Store the new data */
89 2:      EXIT_USER_ACCESS(w6)
90         SET_FAULT_HANDLER(xzr, x6)      /* Reset the fault handler */
91         str     x4, [x2]                /* Store the read data */
92         mov     w0, w5                  /* Result same as store status */
93         ret                             /* Return */
94 END(casueword)
95
96 /*
97  * int fubyte(volatile const void *)
98  */
99 ENTRY(fubyte)
100         ldr     x1, =VM_MAXUSER_ADDRESS
101         cmp     x0, x1
102         b.cs    fsu_fault_nopcb
103         adr     x6, fsu_fault           /* Load the fault handler */
104         SET_FAULT_HANDLER(x6, x1)       /* And set it */
105         ldtrb   w0, [x0]                /* Try loading the data */
106         SET_FAULT_HANDLER(xzr, x1)      /* Reset the fault handler */
107         ret                             /* Return */
108 END(fubyte)
109
110 /*
111  * int fuword(volatile const void *)
112  */
113 ENTRY(fuword16)
114         ldr     x1, =(VM_MAXUSER_ADDRESS-1)
115         cmp     x0, x1
116         b.cs    fsu_fault_nopcb
117         adr     x6, fsu_fault           /* Load the fault handler */
118         SET_FAULT_HANDLER(x6, x1)       /* And set it */
119         ldtrh   w0, [x0]                /* Try loading the data */
120         SET_FAULT_HANDLER(xzr, x1)      /* Reset the fault handler */
121         ret                             /* Return */
122 END(fuword16)
123
124 /*
125  * int32_t fueword32(volatile const void *, int32_t *)
126  */
127 ENTRY(fueword32)
128         ldr     x2, =(VM_MAXUSER_ADDRESS-3)
129         cmp     x0, x2
130         b.cs    fsu_fault_nopcb
131         adr     x6, fsu_fault           /* Load the fault handler */
132         SET_FAULT_HANDLER(x6, x2)       /* And set it */
133         ldtr    w0, [x0]                /* Try loading the data */
134         SET_FAULT_HANDLER(xzr, x2)      /* Reset the fault handler */
135         str     w0, [x1]                /* Save the data in kernel space */
136         mov     w0, #0                  /* Success */
137         ret                             /* Return */
138 END(fueword32)
139
140 /*
141  * long fueword(volatile const void *, int64_t *)
142  * int64_t fueword64(volatile const void *, int64_t *)
143  */
144 ENTRY(fueword)
145 EENTRY(fueword64)
146         ldr     x2, =(VM_MAXUSER_ADDRESS-7)
147         cmp     x0, x2
148         b.cs    fsu_fault_nopcb
149         adr     x6, fsu_fault           /* Load the fault handler */
150         SET_FAULT_HANDLER(x6, x2)       /* And set it */
151         ldtr    x0, [x0]                /* Try loading the data */
152         SET_FAULT_HANDLER(xzr, x2)      /* Reset the fault handler */
153         str     x0, [x1]                /* Save the data in kernel space */
154         mov     x0, #0                  /* Success */
155         ret                             /* Return */
156 EEND(fueword64)
157 END(fueword)
158
159 /*
160  * int subyte(volatile void *, int)
161  */
162 ENTRY(subyte)
163         ldr     x2, =VM_MAXUSER_ADDRESS
164         cmp     x0, x2
165         b.cs    fsu_fault_nopcb
166         adr     x6, fsu_fault           /* Load the fault handler */
167         SET_FAULT_HANDLER(x6, x2)       /* And set it */
168         sttrb   w1, [x0]                /* Try storing the data */
169         SET_FAULT_HANDLER(xzr, x2)      /* Reset the fault handler */
170         mov     x0, #0                  /* Success */
171         ret                             /* Return */
172 END(subyte)
173
174 /*
175  * int suword16(volatile void *, int)
176  */
177 ENTRY(suword16)
178         ldr     x2, =(VM_MAXUSER_ADDRESS-1)
179         cmp     x0, x2
180         b.cs    fsu_fault_nopcb
181         adr     x6, fsu_fault           /* Load the fault handler */
182         SET_FAULT_HANDLER(x6, x2)       /* And set it */
183         sttrh   w1, [x0]                /* Try storing the data */
184         SET_FAULT_HANDLER(xzr, x2)      /* Reset the fault handler */
185         mov     x0, #0                  /* Success */
186         ret                             /* Return */
187 END(suword16)
188
189 /*
190  * int suword32(volatile void *, int)
191  */
192 ENTRY(suword32)
193         ldr     x2, =(VM_MAXUSER_ADDRESS-3)
194         cmp     x0, x2
195         b.cs    fsu_fault_nopcb
196         adr     x6, fsu_fault           /* Load the fault handler */
197         SET_FAULT_HANDLER(x6, x2)       /* And set it */
198         sttr    w1, [x0]                /* Try storing the data */
199         SET_FAULT_HANDLER(xzr, x2)      /* Reset the fault handler */
200         mov     x0, #0                  /* Success */
201         ret                             /* Return */
202 END(suword32)
203
204 /*
205  * int suword(volatile void *, long)
206  */
207 ENTRY(suword)
208 EENTRY(suword64)
209         ldr     x2, =(VM_MAXUSER_ADDRESS-7)
210         cmp     x0, x2
211         b.cs    fsu_fault_nopcb
212         adr     x6, fsu_fault           /* Load the fault handler */
213         SET_FAULT_HANDLER(x6, x2)       /* And set it */
214         sttr    x1, [x0]                /* Try storing the data */
215         SET_FAULT_HANDLER(xzr, x2)      /* Reset the fault handler */
216         mov     x0, #0                  /* Success */
217         ret                             /* Return */
218 EEND(suword64)
219 END(suword)
220
221 ENTRY(setjmp)
222         /* Store the stack pointer */
223         mov     x8, sp
224         str     x8, [x0], #8
225
226         /* Store the general purpose registers and lr */
227         stp     x19, x20, [x0], #16
228         stp     x21, x22, [x0], #16
229         stp     x23, x24, [x0], #16
230         stp     x25, x26, [x0], #16
231         stp     x27, x28, [x0], #16
232         stp     x29, lr, [x0], #16
233
234         /* Return value */
235         mov     x0, #0
236         ret
237 END(setjmp)
238
239 ENTRY(longjmp)
240         /* Restore the stack pointer */
241         ldr     x8, [x0], #8
242         mov     sp, x8
243
244         /* Restore the general purpose registers and lr */
245         ldp     x19, x20, [x0], #16
246         ldp     x21, x22, [x0], #16
247         ldp     x23, x24, [x0], #16
248         ldp     x25, x26, [x0], #16
249         ldp     x27, x28, [x0], #16
250         ldp     x29, lr, [x0], #16
251
252         /* Load the return value */
253         mov     x0, x1
254         ret
255 END(longjmp)
256
257 /*
258  * pagezero, simple implementation
259  */
260 ENTRY(pagezero_simple)
261         add     x1, x0, #PAGE_SIZE
262
263 1:
264         stp     xzr, xzr, [x0], #0x10
265         stp     xzr, xzr, [x0], #0x10
266         stp     xzr, xzr, [x0], #0x10
267         stp     xzr, xzr, [x0], #0x10
268         cmp     x0, x1
269         b.ne    1b
270         ret
271
272 END(pagezero_simple)
273
274 /*
275  * pagezero, cache assisted
276  */
277 ENTRY(pagezero_cache)
278         add     x1, x0, #PAGE_SIZE
279
280         ldr     x2, =dczva_line_size
281         ldr     x2, [x2]
282
283 1:
284         dc      zva, x0
285         add     x0, x0, x2
286         cmp     x0, x1
287         b.ne    1b
288         ret
289
290 END(pagezero_cache)