Deleted Added
full compact
support.S (302408) support.S (319202)
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 *

--- 16 unchanged lines hidden (view full) ---

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>
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 *

--- 16 unchanged lines hidden (view full) ---

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: stable/11/sys/arm64/arm64/support.S 297615 2016-04-06 14:08:10Z andrew $");
33__FBSDID("$FreeBSD: stable/11/sys/arm64/arm64/support.S 319202 2017-05-30 12:26:36Z andrew $");
34
35#include <machine/setjmp.h>
36#include <machine/param.h>
37#include <machine/vmparam.h>
38
39#include "assym.s"
40
41/*
42 * One of the fu* or su* functions failed, return -1.
43 */
44ENTRY(fsu_fault)
45 SET_FAULT_HANDLER(xzr, x1) /* Reset the handler function */
34
35#include <machine/setjmp.h>
36#include <machine/param.h>
37#include <machine/vmparam.h>
38
39#include "assym.s"
40
41/*
42 * One of the fu* or su* functions failed, return -1.
43 */
44ENTRY(fsu_fault)
45 SET_FAULT_HANDLER(xzr, x1) /* Reset the handler function */
46 EXIT_USER_ACCESS_CHECK(w0, x1)
46fsu_fault_nopcb:
47 mov x0, #-1
48 ret
49END(fsu_fault)
50
51/*
52 * int casueword32(volatile uint32_t *, uint32_t, uint32_t *, uint32_t)
53 */
54ENTRY(casueword32)
55 ldr x4, =(VM_MAXUSER_ADDRESS-3)
56 cmp x0, x4
57 b.cs fsu_fault_nopcb
58 adr x6, fsu_fault /* Load the fault handler */
59 SET_FAULT_HANDLER(x6, x4) /* And set it */
47fsu_fault_nopcb:
48 mov x0, #-1
49 ret
50END(fsu_fault)
51
52/*
53 * int casueword32(volatile uint32_t *, uint32_t, uint32_t *, uint32_t)
54 */
55ENTRY(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 SET_FAULT_HANDLER(x6, x4) /* And set it */
61 ENTER_USER_ACCESS(w6, x4)
601: ldxr w4, [x0] /* Load-exclusive the data */
61 cmp w4, w1 /* Compare */
62 b.ne 2f /* Not equal, exit */
63 stxr w5, w3, [x0] /* Store the new data */
64 cbnz w5, 1b /* Retry on failure */
621: ldxr w4, [x0] /* Load-exclusive the data */
63 cmp w4, w1 /* Compare */
64 b.ne 2f /* Not equal, exit */
65 stxr w5, w3, [x0] /* Store the new data */
66 cbnz w5, 1b /* Retry on failure */
67 EXIT_USER_ACCESS(w6)
652: SET_FAULT_HANDLER(xzr, x5) /* Reset the fault handler */
66 str w4, [x2] /* Store the read data */
67 mov x0, #0 /* Success */
68 ret /* Return */
69END(casueword32)
70
71/*
72 * int casueword(volatile u_long *, u_long, u_long *, u_long)
73 */
74ENTRY(casueword)
75 ldr x4, =(VM_MAXUSER_ADDRESS-7)
76 cmp x0, x4
77 b.cs fsu_fault_nopcb
78 adr x6, fsu_fault /* Load the fault handler */
79 SET_FAULT_HANDLER(x6, x4) /* And set it */
682: SET_FAULT_HANDLER(xzr, x5) /* Reset the fault handler */
69 str w4, [x2] /* Store the read data */
70 mov x0, #0 /* Success */
71 ret /* Return */
72END(casueword32)
73
74/*
75 * int casueword(volatile u_long *, u_long, u_long *, u_long)
76 */
77ENTRY(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 SET_FAULT_HANDLER(x6, x4) /* And set it */
83 ENTER_USER_ACCESS(w6, x4)
801: ldxr x4, [x0] /* Load-exclusive the data */
81 cmp x4, x1 /* Compare */
82 b.ne 2f /* Not equal, exit */
83 stxr w5, x3, [x0] /* Store the new data */
84 cbnz w5, 1b /* Retry on failure */
841: ldxr x4, [x0] /* Load-exclusive the data */
85 cmp x4, x1 /* Compare */
86 b.ne 2f /* Not equal, exit */
87 stxr w5, x3, [x0] /* Store the new data */
88 cbnz w5, 1b /* Retry on failure */
89 EXIT_USER_ACCESS(w6)
852: SET_FAULT_HANDLER(xzr, x5) /* Reset the fault handler */
86 str x4, [x2] /* Store the read data */
87 mov x0, #0 /* Success */
88 ret /* Return */
89END(casueword)
90
91/*
92 * int fubyte(volatile const void *)
93 */
94ENTRY(fubyte)
95 ldr x1, =VM_MAXUSER_ADDRESS
96 cmp x0, x1
97 b.cs fsu_fault_nopcb
98 adr x6, fsu_fault /* Load the fault handler */
99 SET_FAULT_HANDLER(x6, x1) /* And set it */
902: SET_FAULT_HANDLER(xzr, x5) /* Reset the fault handler */
91 str x4, [x2] /* Store the read data */
92 mov x0, #0 /* Success */
93 ret /* Return */
94END(casueword)
95
96/*
97 * int fubyte(volatile const void *)
98 */
99ENTRY(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 */
100 ldrb w0, [x0] /* Try loading the data */
105 ldtrb w0, [x0] /* Try loading the data */
101 SET_FAULT_HANDLER(xzr, x1) /* Reset the fault handler */
102 ret /* Return */
103END(fubyte)
104
105/*
106 * int fuword(volatile const void *)
107 */
108ENTRY(fuword16)
109 ldr x1, =(VM_MAXUSER_ADDRESS-1)
110 cmp x0, x1
111 b.cs fsu_fault_nopcb
112 adr x6, fsu_fault /* Load the fault handler */
113 SET_FAULT_HANDLER(x6, x1) /* And set it */
106 SET_FAULT_HANDLER(xzr, x1) /* Reset the fault handler */
107 ret /* Return */
108END(fubyte)
109
110/*
111 * int fuword(volatile const void *)
112 */
113ENTRY(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 */
114 ldrh w0, [x0] /* Try loading the data */
119 ldtrh w0, [x0] /* Try loading the data */
115 SET_FAULT_HANDLER(xzr, x1) /* Reset the fault handler */
116 ret /* Return */
117END(fuword16)
118
119/*
120 * int32_t fueword32(volatile const void *, int32_t *)
121 */
122ENTRY(fueword32)
123 ldr x2, =(VM_MAXUSER_ADDRESS-3)
124 cmp x0, x2
125 b.cs fsu_fault_nopcb
126 adr x6, fsu_fault /* Load the fault handler */
127 SET_FAULT_HANDLER(x6, x2) /* And set it */
120 SET_FAULT_HANDLER(xzr, x1) /* Reset the fault handler */
121 ret /* Return */
122END(fuword16)
123
124/*
125 * int32_t fueword32(volatile const void *, int32_t *)
126 */
127ENTRY(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 */
128 ldr w0, [x0] /* Try loading the data */
133 ldtr w0, [x0] /* Try loading the data */
129 SET_FAULT_HANDLER(xzr, x2) /* Reset the fault handler */
130 str w0, [x1] /* Save the data in kernel space */
131 mov w0, #0 /* Success */
132 ret /* Return */
133END(fueword32)
134
135/*
136 * long fueword(volatile const void *, int64_t *)
137 * int64_t fueword64(volatile const void *, int64_t *)
138 */
139ENTRY(fueword)
140EENTRY(fueword64)
141 ldr x2, =(VM_MAXUSER_ADDRESS-7)
142 cmp x0, x2
143 b.cs fsu_fault_nopcb
144 adr x6, fsu_fault /* Load the fault handler */
145 SET_FAULT_HANDLER(x6, x2) /* And set it */
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 */
138END(fueword32)
139
140/*
141 * long fueword(volatile const void *, int64_t *)
142 * int64_t fueword64(volatile const void *, int64_t *)
143 */
144ENTRY(fueword)
145EENTRY(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 */
146 ldr x0, [x0] /* Try loading the data */
151 ldtr x0, [x0] /* Try loading the data */
147 SET_FAULT_HANDLER(xzr, x2) /* Reset the fault handler */
148 str x0, [x1] /* Save the data in kernel space */
149 mov x0, #0 /* Success */
150 ret /* Return */
151EEND(fueword64)
152END(fueword)
153
154/*
155 * int subyte(volatile void *, int)
156 */
157ENTRY(subyte)
158 ldr x2, =VM_MAXUSER_ADDRESS
159 cmp x0, x2
160 b.cs fsu_fault_nopcb
161 adr x6, fsu_fault /* Load the fault handler */
162 SET_FAULT_HANDLER(x6, x2) /* And set it */
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 */
156EEND(fueword64)
157END(fueword)
158
159/*
160 * int subyte(volatile void *, int)
161 */
162ENTRY(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 */
163 strb w1, [x0] /* Try storing the data */
168 sttrb w1, [x0] /* Try storing the data */
164 SET_FAULT_HANDLER(xzr, x2) /* Reset the fault handler */
165 mov x0, #0 /* Success */
166 ret /* Return */
167END(subyte)
168
169/*
170 * int suword16(volatile void *, int)
171 */
172ENTRY(suword16)
173 ldr x2, =(VM_MAXUSER_ADDRESS-1)
174 cmp x0, x2
175 b.cs fsu_fault_nopcb
176 adr x6, fsu_fault /* Load the fault handler */
177 SET_FAULT_HANDLER(x6, x2) /* And set it */
169 SET_FAULT_HANDLER(xzr, x2) /* Reset the fault handler */
170 mov x0, #0 /* Success */
171 ret /* Return */
172END(subyte)
173
174/*
175 * int suword16(volatile void *, int)
176 */
177ENTRY(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 */
178 strh w1, [x0] /* Try storing the data */
183 sttrh w1, [x0] /* Try storing the data */
179 SET_FAULT_HANDLER(xzr, x2) /* Reset the fault handler */
180 mov x0, #0 /* Success */
181 ret /* Return */
182END(suword16)
183
184/*
185 * int suword32(volatile void *, int)
186 */
187ENTRY(suword32)
188 ldr x2, =(VM_MAXUSER_ADDRESS-3)
189 cmp x0, x2
190 b.cs fsu_fault_nopcb
191 adr x6, fsu_fault /* Load the fault handler */
192 SET_FAULT_HANDLER(x6, x2) /* And set it */
184 SET_FAULT_HANDLER(xzr, x2) /* Reset the fault handler */
185 mov x0, #0 /* Success */
186 ret /* Return */
187END(suword16)
188
189/*
190 * int suword32(volatile void *, int)
191 */
192ENTRY(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 */
193 str w1, [x0] /* Try storing the data */
198 sttr w1, [x0] /* Try storing the data */
194 SET_FAULT_HANDLER(xzr, x2) /* Reset the fault handler */
195 mov x0, #0 /* Success */
196 ret /* Return */
197END(suword32)
198
199/*
200 * int suword(volatile void *, long)
201 */
202ENTRY(suword)
203EENTRY(suword64)
204 ldr x2, =(VM_MAXUSER_ADDRESS-7)
205 cmp x0, x2
206 b.cs fsu_fault_nopcb
207 adr x6, fsu_fault /* Load the fault handler */
208 SET_FAULT_HANDLER(x6, x2) /* And set it */
199 SET_FAULT_HANDLER(xzr, x2) /* Reset the fault handler */
200 mov x0, #0 /* Success */
201 ret /* Return */
202END(suword32)
203
204/*
205 * int suword(volatile void *, long)
206 */
207ENTRY(suword)
208EENTRY(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 */
209 str x1, [x0] /* Try storing the data */
214 sttr x1, [x0] /* Try storing the data */
210 SET_FAULT_HANDLER(xzr, x2) /* Reset the fault handler */
211 mov x0, #0 /* Success */
212 ret /* Return */
213EEND(suword64)
214END(suword)
215
216/*
217 * fuswintr and suswintr are just like fusword and susword except that if
218 * the page is not in memory or would cause a trap, then we return an error.
219 * The important thing is to prevent sleep() and switch().
220 */
221
222/*
223 * Special handler so the trap code knows not to sleep.
224 */
225ENTRY(fsu_intr_fault)
226 SET_FAULT_HANDLER(xzr, x1) /* Reset the handler function */
215 SET_FAULT_HANDLER(xzr, x2) /* Reset the fault handler */
216 mov x0, #0 /* Success */
217 ret /* Return */
218EEND(suword64)
219END(suword)
220
221/*
222 * fuswintr and suswintr are just like fusword and susword except that if
223 * the page is not in memory or would cause a trap, then we return an error.
224 * The important thing is to prevent sleep() and switch().
225 */
226
227/*
228 * Special handler so the trap code knows not to sleep.
229 */
230ENTRY(fsu_intr_fault)
231 SET_FAULT_HANDLER(xzr, x1) /* Reset the handler function */
232 EXIT_USER_ACCESS_CHECK(w0, x1)
227 mov x0, #-1
228 ret
229END(fsu_fault)
230
231/*
232 * int fuswintr(void *)
233 */
234ENTRY(fuswintr)
235 ldr x1, =(VM_MAXUSER_ADDRESS-3)
236 cmp x0, x1
237 b.cs fsu_fault_nopcb
238 adr x6, fsu_intr_fault /* Load the fault handler */
239 SET_FAULT_HANDLER(x6, x1) /* And set it */
233 mov x0, #-1
234 ret
235END(fsu_fault)
236
237/*
238 * int fuswintr(void *)
239 */
240ENTRY(fuswintr)
241 ldr x1, =(VM_MAXUSER_ADDRESS-3)
242 cmp x0, x1
243 b.cs fsu_fault_nopcb
244 adr x6, fsu_intr_fault /* Load the fault handler */
245 SET_FAULT_HANDLER(x6, x1) /* And set it */
240 ldr w0, [x0] /* Try loading the data */
246 ldtr w0, [x0] /* Try loading the data */
241 SET_FAULT_HANDLER(xzr, x1) /* Reset the fault handler */
242 ret /* Return */
243END(fuswintr)
244
245/*
246 * int suswintr(void *base, int word)
247 */
248ENTRY(suswintr)
249 ldr x2, =(VM_MAXUSER_ADDRESS-3)
250 cmp x0, x2
251 b.cs fsu_fault_nopcb
252 adr x6, fsu_intr_fault /* Load the fault handler */
253 SET_FAULT_HANDLER(x6, x2) /* And set it */
247 SET_FAULT_HANDLER(xzr, x1) /* Reset the fault handler */
248 ret /* Return */
249END(fuswintr)
250
251/*
252 * int suswintr(void *base, int word)
253 */
254ENTRY(suswintr)
255 ldr x2, =(VM_MAXUSER_ADDRESS-3)
256 cmp x0, x2
257 b.cs fsu_fault_nopcb
258 adr x6, fsu_intr_fault /* Load the fault handler */
259 SET_FAULT_HANDLER(x6, x2) /* And set it */
254 str w1, [x0] /* Try storing the data */
260 sttr w1, [x0] /* Try storing the data */
255 SET_FAULT_HANDLER(xzr, x2) /* Reset the fault handler */
256 mov x0, #0 /* Success */
257 ret /* Return */
258END(suswintr)
259
260ENTRY(setjmp)
261 /* Store the stack pointer */
262 mov x8, sp

--- 67 unchanged lines hidden ---
261 SET_FAULT_HANDLER(xzr, x2) /* Reset the fault handler */
262 mov x0, #0 /* Success */
263 ret /* Return */
264END(suswintr)
265
266ENTRY(setjmp)
267 /* Store the stack pointer */
268 mov x8, sp

--- 67 unchanged lines hidden ---